« PREV : 1 : 2 : 3 : 4 : 5 : ... 6 : NEXT »

BugCheck 0x50

Posted 2010/07/05 12:17
자주 만날수 있는 디버깅 오류 코드로 PAGE_FAULT_IN_NONPAGED_AREA 에 관한 오류 입니다.

PAGED와 NONPAGED AREA 란
윈도우에서 PAGE는 정보를 사용하기위한 정보를 저장해 놓은 것이라고 생각 하면 되는데, 기본 크기는 4096Byte 입니다. PAGE라는 용어는 여러 곳에서 사용되게 되며, NONPAGED란 가상 메모리화 할 수 없는 영역, 즉 시스템 메모리(실 메모리) 영역에서 오류가 발생했다는 판단 하시면 됩니다.

오류가 발생하는 원인
이유는 크게 2가지로 보실수 있습니다.
첫째는 함수로 지정한 공간이 너무 작은 경우 입력값이 커서 발생할 수 있으며,
두번째는 위의 반대 상황으로, 입력값이 너무 커서 발생할 수 있습니다.
같은 상황 같지만, 장애를 조치하는 방식에 있어서는 엄연히 다른 부분이 되겠지요.

해결 방법
어떠한 값이 잘못된 메모리 영역을 사용하도록 하였는지 확인하는게 키 포인트로,
잘못된 메모리를 찾았다면, 어떻게 잘못되게 되었는지 역으로 트래킹 해보아야 합니다.
사용할 만한 명령들
!analyze -v
.trap
.frame
dv
dt

보다 자세한 내용은 windbg help 파일을 참조하세요



저작자 표시 비영리
Write your message and submit
최근  http://blogs.msdn.com/b/ntdebugging/ 에서 제공한 팁으로, CDDB(Critical Device Database)에 대한 내용과 나타날수 있는 장애에 대한 내용이 있습니다.

 BIOS를 업데이트 하고, Bugcheck 0x7B(Inaccessible_Boot_Device)를 나타낼 때 먼저 !devnode 명령을 통해 현재 어떤 디바이스에서 장애가 발생하였는지(Problem 원인) 확인하고, 해당 디바이스의 인스턴스를 확인하여(업데이트시 인스턴스는 동일해야 합니다.), 기존 레지스트리에 등록된 인스턴스 (HKLM\System\CurrentControlSet\ENUM\)와 차이가 없는지 확인하여 설치 파일의 Inf 내용을 수정하거나, 레지스트리를 수정(inf 수정 추천)하여 조치할수 있습니다.

저작자 표시 비영리
Write your message and submit

 

많은 분들이 메모리 분석을 시도 하고 있습니다.

 

하지만 어디서부터 시작해야할지 막막할때가 많죠

제가 생각하기에 가장 먼저 해야할일은 스택의 구조를 파악하는 일을 해야한다 생각합니다.

컴퓨터를 하시는 분들은 메모리가 스택구조로 되어 있다고 알고 있으실 겁니다.

선입후출 이라는 것이죠

 

그럼 다음 내용을 보고 어떤 내용인지 알수 있을까요?

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

    47 01001397 e824000000 call 05stackdesc!Sum (010013c0)

    48 0100139c 8b45f0 mov eax,dword ptr [ebp-10h]

    48 0100139f 50 push eax

    48 010013a0 6874110001 push offset 05stackdesc!`string' (01001174)

    48 010013a5 ff1584100001 call dword ptr [05stackdesc!_imp__wprintf (01001084)]

    48 010013ab 83c408 add esp,8

     49 010013ae 8be5 mov esp,ebp

    49 010013b0 5d pop ebp

    49 010013b1 c3 ret
자 선입후출의 의미로만 알수 있을까요?

이 의미만으로는 아무것도 알수가 없지요..

 

정확히 메모리의 구조를 이해하기 위해서는 스레드들이 어떻게 처리되는지 더 자세히 확인해볼 필요가 있습니다.

 

그럼 위 구조 내용을 통해, 확인해 보도록하겠습니다.

 

스택은 아래와 같이 구분할 수 있습니다.

함수 도입부

함수 코드

함수 종결부

 

그러다면 함수 도입부를 확인해 보도록 하겠습니다.

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

양이 많죠? 위 부분이 함수 도입부 인데, 함수를 저장할 공간을 할당하고, 기존 포인터 위치를 기억하는 게 주된 목적 입니다.

위 부분에서 ebp에 대해 알아 보도록 합시다.

ebp는 알아두어야 할 내용이 항상 주어진 프레임의 베이스 포인터(Base Pointer)를 포함한다고 생각하시면 됩니다.

그럼 아래내용은 무엇을 뜻하는 것일까요?

42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

Push 명령을 통해 ebp를 집어넣으라는 명령으로, Stack에 자료를 집어넣을 때 사용하는 것입니다.

쉽게 말해 ebp를 집어넣으라는 뜻이지요

그래서 mov 명령으로 esp 값(Stack Pointer)을 ebp에 저장하라는 명령이 나오게됩니다.

esp는 현재 스택 포인터 값으로, 이 포인터 위치는 항상 변하게 되므로, 항상 호출 이전의 원래 상태로 복귀됨을 보장하여야하는 메모리 구조상 esp의 복귀 주소를 사용할수 없기 때문에 ebp를 통해 복귀할 수 있는 주소를 저장하게 됩니다. (이 행동의 거희 모든 스택의 기본 동작으로 들어가 있습니다.)

mov edi,edi는 긴급 패치를 위해 사용하는데 대부분 nop(no operation)으로 상태가 됩니다. 가용성 측면으로 비사용시간을 줄이기위해 필수적으로 사용하게 됩니다. 이는 나중에 jmp 코드를 이용하기 위해 넣어 둔것이라고 생각하시면 됩니다.

 

자 그럼 도입부분으로 프레임의 베이스 포인터 위치를 ebp에 저장하여 프레임 복귀위치를 저장하였습니다.

이제 다음 스택을 보도록 하겠습니다.

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

esp, 14h가 의미하는건 14h를 10진수로 변환해 보면, 20바이트가 되며, sub는 빼는것으로, 20바이트 만큼 공간을 생성하도록 되어 있습니다.

왜 이렇게 공간을 생성하는게 빼기를 하였을까요?

메모리의 저장 위치를 잘 보시면 저장 위치의 값이 감소하도록 되어 있습니다.

즉 밑으로 갈수록 값이 감소하고 있는것이지요

그래서 아래 공간은 빼기를 통해 확보하게 됩니다.

그렇게 확보한 공간에 ebp(베이스 포인터)의 위치 값을 이용하여 (베이스 포인터는 절대 위치 값처럼 그 프레임 내에서는 변화하지 않기 때문에 변수 저장과 같은 절대 위치가 필요한 값 저장에 사용하게 됩니다.)스택기반 지역 변수를 초기화 하게 됩니다.

그 내용이

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

위 부분이 되겠습니다.

그리고 포인터 전달 명령인 lea를 통해 인자를 스택에 저장 합니다.

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

이렇게 지역 변수를 다 저장하고 나면, Call 명령을 통해 해당 변수를 사용하게 됩니다.

그리고 수행을 마치고 마지막에 esp에 처음 저장한 ebp를 대입하여, 복귀하고, 해당 프레임을 빠져 나오게 됩니다.

49 010013ae 8be5 mov esp,ebp

    49 010013b0 5d pop ebp

    49 010013b1 c3 ret

이렇게 하나하나의 프레임의 복귀 주소를 저장하고 변수를 저장후 Call을 통해 해당 명령을 수행하는 구조가 메모리의 기본 구조가 되겠습니다.

^^;

아직 알아야하는부분은 더 많지만 오늘은 스택의 기본 구조 1은 이 정도로 마무리 하도록 하겠습니다.

  1. | 2010/06/21 21:52 | PERMALINK | EDIT | REPLY |

    비밀댓글 입니다

  2. BlogIcon 올엠

    | 2010/07/07 14:27 | PERMALINK | EDIT |

    안녕하세요 늦게 댓글을 달게 되네요,
    그런데 어쩌죠?
    현재 초대장을 주변분들에게 모두드려서 없는 상태에요..
    만약 나중에 생기게 되면 메일로 보내드릴께요 ^^

Write your message and submit

메모리 깨짐 증상으로 인해 발생하는 Clush 상황에 따른 덤프 분석내용 입니다.


분석 내용

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: fffffa821440c7fe, memory referenced.
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation.
Arg3: fffffa6009fe1763, If non-zero, the instruction address which referenced the bad memory
 address.
Arg4: 0000000000000005, (reserved)

Debugging Details:
------------------

PEB is paged out (Peb.Ldr = 000007ff`fffdc018).  Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 000007ff`fffdc018).  Type ".hh dbgerr001" for details

READ_ADDRESS:  fffffa821440c7fe

FAULTING_IP:
V3Flt2K+11763
fffffa60`09fe1763 0fb70441        movzx   eax,word ptr [rcx+rax*2]

MM_INTERNAL_CODE:  5

IMAGE_NAME:  V3Flt2K.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  4afbd730

MODULE_NAME: V3Flt2K

FAULTING_MODULE: fffffa6009fd0000 V3Flt2K

DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT

BUGCHECK_STR:  0x50

PROCESS_NAME:  w3wp.exe

CURRENT_IRQL:  0

TRAP_FRAME:  fffffa600a7f22e0 -- (.trap 0xfffffa600a7f22e0)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=00000000ffffffff rbx=0000000000000000 rcx=fffffa801440c800
rdx=fffffa80153355e0 rsi=0000000000000000 rdi=0000000000000000
rip=fffffa6009fe1763 rsp=fffffa600a7f2470 rbp=fffffa8011d1d450
 r8=fffffa801440c800  r9=fffffa800acf5910 r10=0000000000000001
r11=0000000000000002 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz ac po nc
V3Flt2K+0x11763:
fffffa60`09fe1763 0fb70441        movzx   eax,word ptr [rcx+rax*2] ds:24d0:c7fe=????
Resetting default scope

LAST_CONTROL_TRANSFER:  from fffff8000165bce0 to fffff8000164dbd0

STACK_TEXT: 
fffffa60`0a7f21e8 fffff800`0165bce0 : 00000000`00000050 fffffa82`1440c7fe 00000000`00000000 fffffa60`0a7f22e0 : nt!KeBugCheckEx
fffffa60`0a7f21f0 fffff800`0164c759 : 00000000`00000000 00000000`00000000 fffffa80`0bb78700 00000000`00000000 : nt!MmAccessFault+0x4f0
fffffa60`0a7f22e0 fffffa60`09fe1763 : 00000000`00000000 00000000`00000000 fffffa80`11d1d5a0 fffffa60`09fe1182 : nt!KiPageFault+0x119
fffffa60`0a7f2470 fffffa60`09fe1182 : fffffa80`1440c800 fffffa60`09fd632f fffffa80`11d1d500 fffffa60`0a7f2598 : V3Flt2K+0x11763
fffffa60`0a7f2490 fffffa60`09fd64f6 : fffffa80`15335510 fffffa80`153355e0 fffffa80`1440c800 fffffa80`0acf5910 : V3Flt2K+0x11182
fffffa60`0a7f24f0 fffffa60`00d4505a : fffffa80`11d1d500 fffffa60`0a7f2598 fffffa60`0a7f2580 00000000`00000010 : V3Flt2K+0x64f6
fffffa60`0a7f2540 fffffa60`00d4432c : 00000000`00000000 fffffa80`0fb7e300 fffffa80`0c666f00 fffffa80`1000000c : fltmgr!FltpPerformPreCallbacks+0x28a
fffffa60`0a7f2620 fffffa60`00d60256 : fffffa80`09dac040 fffffa80`0c666f20 fffffa80`0fb7e0c0 fffffa60`0a7f26a0 : fltmgr!FltpPassThroughInternal+0x3c
fffffa60`0a7f2650 fffff800`018d5393 : 00000000`00000005 fffffa80`0ccf4b10 00000000`00000040 00000000`00000000 : fltmgr!FltpCreate+0x247
fffffa60`0a7f2700 fffff800`018cf069 : fffffa80`0960dcc0 00000000`00000000 fffffa80`1f44b010 fffff800`018fa501 : nt!IopParseDevice+0x5e3
fffffa60`0a7f28a0 fffff800`018d2f54 : 00000000`00000000 fffffa80`18f14101 00000000`00000040 00000000`00000000 : nt!ObpLookupObjectName+0x5eb
fffffa60`0a7f29b0 fffff800`018df430 : 00120089`80100080 00000000`0909ddb8 fffffa80`1e07e501 fffffa80`1e07e540 : nt!ObOpenObjectByName+0x2f4
fffffa60`0a7f2a80 fffff800`018dff5c : 00000000`0909dd48 00000000`80100080 fffffa80`1d9db060 00000000`0909dd68 : nt!IopCreateFile+0x290
fffffa60`0a7f2b20 fffff800`0164d673 : fffffa80`1d9db060 00000000`0909fcc8 fffffa60`0a7f2bc8 fffff800`018cc4d4 : nt!NtCreateFile+0x78
fffffa60`0a7f2bb0 00000000`777b5fca : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
00000000`0909dcd8 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x777b5fca


STACK_COMMAND:  kb

FOLLOWUP_IP:
V3Flt2K+11763
fffffa60`09fe1763 0fb70441        movzx   eax,word ptr [rcx+rax*2]

SYMBOL_STACK_INDEX:  3

SYMBOL_NAME:  V3Flt2K+11763

FOLLOWUP_NAME:  MachineOwner

FAILURE_BUCKET_ID:  X64_0x50_V3Flt2K+11763

BUCKET_ID:  X64_0x50_V3Flt2K+11763

Followup: MachineOwner
---------

3: kd> .trap 0xfffffa600a7f22e0
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=00000000ffffffff rbx=0000000000000000 rcx=fffffa801440c800
rdx=fffffa80153355e0 rsi=0000000000000000 rdi=0000000000000000
rip=fffffa6009fe1763 rsp=fffffa600a7f2470 rbp=fffffa8011d1d450
 r8=fffffa801440c800  r9=fffffa800acf5910 r10=0000000000000001
r11=0000000000000002 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz ac po nc
V3Flt2K+0x11763:
fffffa60`09fe1763 0fb70441        movzx   eax,word ptr [rcx+rax*2] ds:24d0:c7fe=????

3: kd> dd fffffa821440c7fe <-- 잘못된 메모리 영역 참조
fffffa82`1440c7fe  ???????? ???????? ???????? ????????
fffffa82`1440c80e  ???????? ???????? ???????? ????????
fffffa82`1440c81e  ???????? ???????? ???????? ????????
fffffa82`1440c82e  ???????? ???????? ???????? ????????
fffffa82`1440c83e  ???????? ???????? ???????? ????????
fffffa82`1440c84e  ???????? ???????? ???????? ????????
fffffa82`1440c85e  ???????? ???????? ???????? ????????
fffffa82`1440c86e  ???????? ???????? ???????? ????????

3: kd> db fffffa801440c800
fffffa80`1440c800  00 00 0d 17 80 fa ff ff-69 00 63 00 65 00 5c 00  ........i.c.e.\. <--- 깨진부분
fffffa80`1440c810  48 00 61 00 72 00 64 00-64 00 69 00 73 00 6b 00  H.a.r.d.d.i.s.k.
fffffa80`1440c820  56 00 6f 00 6c 00 75 00-6d 00 65 00 32 00 5c 00  V.o.l.u.m.e.2.\.
fffffa80`1440c830  48 00 59 00 55 00 4e 00-44 00 41 00 49 00 5c 00  H.Y.U.N.D.A.I.\.
fffffa80`1440c840  30 00 34 00 20 00 1c ac-1c bc 8c c1 a4 c2 5c 00  0.4. .........\.
fffffa80`1440c850  30 00 34 00 20 00 31 00-30 00 20 00 57 00 65 00  0.4. .1.0. .W.e.

조치 방법

안철수 연구소 확인결과 타고객사 유사건으로 확인한 내역이 있어 이에 따른 안정성을 위해 핫픽스를 제공

v3Net7.0 제품에서 메모리 관련 방어 코드 수정

[패치내용]
파일 path가 비 정상 적으로 입력되거나 해당 메모리가 깨져 있을 경우에 대한 방어 코드 추가

[변경사항]
파일 버퍼의 유효성 확인 코드 추가

[변경모듈]
v3flt2k.sys 7.1.0.15

저작자 표시 비영리
Write your message and submit
C 컴파일시 아래 오류 메세지를 확인하실수 있습니다.

Duplicate symbol warning

이 오류의 원인은 변수를 선언후 정의가 된 변수를 다시 정의하여, 중복되었다고 나타나는 오류 입니다.

보통 이런 상황인것이지요.


int global; //이는 임시 정의만 한상태입니다.
int global = 1; //이제 정의를 한 상태가된것이죠, global은 1!

extern int global  // global을 선언하였습니다.
extern int global = 0; // 여기서 다시 global은 0이라고 재정의했내요.

또다른 예
int i; // 임시정의
ini i=0; // 정의
extern int i; // 선언
extern int i=0; // 정의

위와 같이 2번 정의를 하여 발생하는 경고 메세지 입니다.

전역 변수에서 초기 정의를 하여서 발생하는 문제일 가능성이 큽니다.
전역변수에서는 임시 정의만 하시고, include 하여 사용하시는게 증복 심볼 에러를 막을수 있습니다.
저작자 표시 비영리

'프로그래밍 > C/C++' 카테고리의 다른 글

Duplicate symbol warning시 확인해야 하는 부분  (0) 2010/04/01
시스템 정보 GetVersionEx  (0) 2009/08/14
시스템 정보 GetComputerName  (0) 2009/08/14
시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
Write your message and submit

.DMP 확장자 연결하기

Posted 2010/02/23 09:29
Dump파일을 일반적인 파일 오픈 식으로 windbg와 연결하면 정상적으로 Dump 파일을 오픈 할수 없다.

windbg 옵션중 유용한 옵션이 있다, 바로, .dmp 확장자를 연결시켜주는 옵션으로 아래 명령을 실행창에 입력하여 보자

windbg -IA
(대소문자 구분함!)

이제 덤프파일을 더블클릭하면 windbg로 정상적으로 오픈되는것을 확인할수 있다.



저작자 표시 비영리
Write your message and submit

오랫만에 메모리 덤프 분석한 내용이 있어 글을 올립니다.

현상 :
eip 포인터가 갑자기 참조할수 없는 주소를 참조하여 0xd1 오류와 함께 재부팅됨

분석 내용 :
0: kd> dps fffff80003a8f080-50 fffff80003a8f080+50
fffff800`03a8f030  fffffa80`0b895820
fffff800`03a8f038  fffffa60`0107fe3d tcpip! ?? ::FNODOBFM::`string'+0x6ff4
fffff800`03a8f040  00000000`00001310
fffff800`03a8f048  00000000`00000000
fffff800`03a8f050  fffff800`03a8f0e0
fffff800`03a8f058  fffff800`03a8f0f0
fffff800`03a8f060  fffffa80`094d1000
fffff800`03a8f068  fffffa80`096a8430
fffff800`03a8f070  00000000`00000000
fffff800`03a8f078  00000000`00000000
fffff800`03a8f080  fffffa80`1133a02a
fffff800`03a8f088  f80003a8`f1000130
fffff800`03a8f090  fffffa80`0c59ffff
fffff800`03a8f098  f80003a8`90700fff
fffff800`03a8f0a0  fffffa80`0b89ffff
fffff800`03a8f0a8  fffffa80`0b8958b8
fffff800`03a8f0b0  fffffa80`0c59bb40
fffff800`03a8f0b8  fffffa80`09514280
fffff800`03a8f0c0  fffffa80`0b8958b8
fffff800`03a8f0c8  fffffa60`0106e547 tcpip!TcpDeliverReceive+0x67
fffff800`03a8f0d0  00000000`00000001

장애시 진행되었던 CPU 동작 스레드
0: kd> u fffff80003a8f020
fffff800`03a8f020 0000            add     byte ptr [rax],al <-- 장애시 동작하던 위치 다음 위치로 이동하여야 하나, 다음위치를 지정하는 rip는 참조할수 없는 위치를 지정함.
fffff800`03a8f022 0000            add     byte ptr [rax],al
fffff800`03a8f024 0000            add     byte ptr [rax],al
fffff800`03a8f026 0000            add     byte ptr [rax],al
fffff800`03a8f028 c09b080a80faff  rcr     byte ptr [rbx-57FF5F8h],0FFh
fffff800`03a8f02f ff20            jmp     qword ptr [rax]
fffff800`03a8f031 58              pop     rax
fffff800`03a8f032 890b            mov     dword ptr [rbx],ecx

0: kd> dd fffffa80`1133b630 <- 참조할수 없는 메모리
Page 2ee93b not present in the dump file. Type ".hh dbgerr004" for details
fffffa80`1133b630  ???????? ???????? ???????? ????????
fffffa80`1133b640  ???????? ???????? ???????? ????????
fffffa80`1133b650  ???????? ???????? ???????? ????????
fffffa80`1133b660  ???????? ???????? ???????? ????????
fffffa80`1133b670  ???????? ???????? ???????? ????????
fffffa80`1133b680  ???????? ???????? ???????? ????????
fffffa80`1133b690  ???????? ???????? ???????? ????????
fffffa80`1133b6a0  ???????? ???????? ???????? ????????

0: kd> !thread
THREAD fffff80001787b80  Cid 0000.0000  Teb: 0000000000000000 Win32Thread: 0000000000000000 RUNNING on processor 0
Not impersonating
DeviceMap                 fffff88000007390
Owning Process            fffff800017880c0       Image:         Idle
Attached Process          fffffa8008f3a3d0       Image:         System
Wait Start TickCount      131742600      Ticks: 166 (0:00:00:02.593)
Context Switch Count      719945911            
UserTime                  00:00:00.000
KernelTime                19 Days 19:29:38.046
Win32 Start Address nt!KiIdleLoop (0xfffff8000166ce10)
Stack Init fffff80003a90db0 Current fffff80003a90d40
Base fffff80003a91000 Limit fffff80003a8b000<- 제한 영역 Call 0
Priority 16 BasePriority 0 PriorityDecrement 0 IoPriority 0 PagePriority 0
Child-SP          RetAddr           : Args to Child                                                           : Call Site
fffff800`03a8ed48 fffff800`0166246e : 00000000`0000000a 00000000`00000000 00000000`00000002 00000000`00000001 : nt!KeBugCheckEx
fffff800`03a8ed50 fffff800`0166134b : 00000000`00000001 00000000`00000000 fffff800`03a8ee00 fffffa80`1133a02a : nt!KiBugCheckDispatch+0x6e
fffff800`03a8ee90 fffffa80`1133b630 : 00000000`00000000 fffffa80`0a089bc0 fffffa80`0b895820 fffffa60`0107fe3d : nt!KiPageFault+0x20b (TrapFrame @ fffff800`03a8ee90)
fffff800`03a8f020 00000000`00000000 : fffffa80`0a089bc0 fffffa80`0b895820 fffffa60`0107fe3d 00000000`00001310 : 0xfffffa80`1133b630

동작 중이던 작업
0: kd> dps fffff80003a8f080-50 fffff80003a8f080+50
fffff800`03a8f030  fffffa80`0b895820
fffff800`03a8f038  fffffa60`0107fe3d tcpip! ?? ::FNODOBFM::`string'+0x6ff4 <-TCP Traffic 전달 진행
fffff800`03a8f040  00000000`00001310
fffff800`03a8f048  00000000`00000000
fffff800`03a8f050  fffff800`03a8f0e0
fffff800`03a8f058  fffff800`03a8f0f0
fffff800`03a8f060  fffffa80`094d1000
fffff800`03a8f068  fffffa80`096a8430
fffff800`03a8f070  00000000`00000000
fffff800`03a8f078  00000000`00000000
fffff800`03a8f080  fffffa80`1133a02a
fffff800`03a8f088  f80003a8`f1000130
fffff800`03a8f090  fffffa80`0c59ffff
fffff800`03a8f098  f80003a8`90700fff
fffff800`03a8f0a0  fffffa80`0b89ffff
fffff800`03a8f0a8  fffffa80`0b8958b8
fffff800`03a8f0b0  fffffa80`0c59bb40
fffff800`03a8f0b8  fffffa80`09514280
fffff800`03a8f0c0  fffffa80`0b8958b8
fffff800`03a8f0c8  fffffa60`0106e547 tcpip!TcpDeliverReceive+0x67
fffff800`03a8f0d0  00000000`00000001


원인 :
EIP 포인터의 변경은 임의로 일어날수 없는것으로, 하드웨어의 문제로 발생했을 가능성이 큽니다.
MS에서는 Vmware의 x64 bit Windows 2003 및 2008에서 임의의 재부팅을 발생하는 현상에 대한 핫픽스를 제공하였습니다.

해결 방안 :
아래 문서의 핫픽스 적용으로 해결이 가능합니다.
해당 내용
http://support.microsoft.com/kb/950772

참고
Vmware 관련 내용
Windows 2003 R2 x64 virtual machine fails with STOP Error: 0x000000D1 or STOP Error: 0x0000001E
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1004498

저작자 표시 비영리
Write your message and submit
 

lkd> !handle

………………………….

………………………….

………………………….

0114: Object: 85324a48  GrantedAccess: 00120089 Entry: e7afb228

Object: 85324a48  Type: (8a527560) File

    ObjectHeader: 85324a30 (old version)

        HandleCount: 1  PointerCount: 2

        Directory Object: 00000000  Name: \symbols.pub\ntkrpamp.pdb\D8743252F83B4F59985D6E19F33BFCAF1\ntkrpamp.pdb {HarddiskVolume1}

 

0118: Object: 85933148  GrantedAccess: 00100003 Entry: e7afb230

Object: 85933148  Type: (8a53c490) Event

    ObjectHeader: 85933130 (old version)

        HandleCount: 1  PointerCount: 1

 

lkd> !fileobj 85324a48

 

\symbols.pub\ntkrpamp.pdb\D8743252F83B4F59985D6E19F33BFCAF1\ntkrpamp.pdb

 

Device Object: 0x89ac36c8   \Driver\Ftdisk

Vpb: 0x8a46d6a8

Event signalled

Access: Read SharedRead SharedDelete

 

Flags:  0x1c0042

Synchronous IO

Cache Supported

Handle Created

Fast IO Read

Random Access

 

FsContext: 0xe7bcad90        FsContext2: 0xe7bcaee8

Private Cache Map: 0x847eaab0

CurrentByteOffset: 19d838

Cache Data:

  Section Object Pointers: 848144c4

  Shared Cache Map: 847ea9d8         File Offset: 19d838 in VACB number 6

  Vacb: 8a52a4a8

  Your data is at: d1d1d838

lkd> dt _FILE_OBJECT 85324a48

nt!_FILE_OBJECT

   +0x000 Type             : 5

   +0x002 Size             : 112

   +0x004 DeviceObject     : 0x89ac36c8 _DEVICE_OBJECT

   +0x008 Vpb              : 0x8a46d6a8 _VPB

   +0x00c FsContext        : 0xe7bcad90

   +0x010 FsContext2       : 0xe7bcaee8

   +0x014 SectionObjectPointer : 0x848144c4 _SECTION_OBJECT_POINTERS

   +0x018 PrivateCacheMap  : 0x847eaab0

   +0x01c FinalStatus      : 0

   +0x020 RelatedFileObject : (null)

   +0x024 LockOperation    : 0 ''

   +0x025 DeletePending    : 0 ''

   +0x026 ReadAccess       : 0x1 ''

   +0x027 WriteAccess      : 0 ''

   +0x028 DeleteAccess     : 0 ''

   +0x029 SharedRead       : 0x1 ''

   +0x02a SharedWrite      : 0 ''

   +0x02b SharedDelete     : 0x1 ''

   +0x02c Flags            : 0x1c0042

   +0x030 FileName         : _UNICODE_STRING "\symbols.pub\ntkrpamp.pdb\D8743252F83B4F59985D6E19F33BFCAF1\ntkrpamp.pdb"

   +0x038 CurrentByteOffset : _LARGE_INTEGER 0x19d838

   +0x040 Waiters          : 0

   +0x044 Busy             : 0

   +0x048 LastLock         : (null)

   +0x04c Lock             : _KEVENT

   +0x05c Event            : _KEVENT

   +0x06c CompletionContext : (null)

lkd> dt _SECTION_OBJECT_POINTERS 0x848144c4

nt!_SECTION_OBJECT_POINTERS

   +0x000 DataSectionObject : 0x847cb0b0

   +0x004 SharedCacheMap   : 0x847ea9d8

   +0x008 ImageSectionObject : (null)

lkd> dt _SHARED_CACHE_MAP 0x847ea9d8

nt!_SHARED_CACHE_MAP

   +0x000 NodeTypeCode     : 767

   +0x002 NodeByteSize     : 304

   +0x004 OpenCount        : 1

   +0x008 FileSize         : _LARGE_INTEGER 0x1a4c00

   +0x010 BcbList          : _LIST_ENTRY [ 0x847ea9e8 - 0x847ea9e8 ]

   +0x018 SectionSize      : _LARGE_INTEGER 0x1c0000

   +0x020 ValidDataLength  : _LARGE_INTEGER 0x1a4c00

   +0x028 ValidDataGoal    : _LARGE_INTEGER 0x1a4c00

   +0x030 InitialVacbs     : [4] (null)

   +0x040 Vacbs            : 0x84f47338  -> 0x8a529068 _VACB

   +0x044 FileObject       : 0x85324a48 _FILE_OBJECT

   +0x048 ActiveVacb       : 0x8a52a4a8 _VACB

   +0x04c NeedToZero       : (null)

   +0x050 ActivePage       : 0x180

   +0x054 NeedToZeroPage   : 0

   +0x058 ActiveVacbSpinLock : 0

   +0x05c VacbActiveCount  : 1

   +0x060 DirtyPages       : 0

   +0x064 SharedCacheMapLinks : _LIST_ENTRY [ 0x84f7c06c - 0x844d78bc ]

   +0x06c Flags            : 0x1000

   +0x070 Status           : 0

   +0x074 Mbcb             : (null)

   +0x078 Section          : 0xeb326d50

   +0x07c CreateEvent      : (null)

   +0x080 WaitOnActiveCount : (null)

   +0x084 PagesToWrite     : 0

   +0x088 BeyondLastFlush  : 0

   +0x090 Callbacks        : 0xb9c2d22c _CACHE_MANAGER_CALLBACKS

   +0x094 LazyWriteContext : 0xe7bcad90

   +0x098 PrivateList      : _LIST_ENTRY [ 0x847eaafc - 0x847eaafc ]

   +0x0a0 LogHandle        : (null)

   +0x0a4 FlushToLsnRoutine : (null)

   +0x0a8 DirtyPageThreshold : 0

   +0x0ac LazyWritePassCount : 0

   +0x0b0 UninitializeEvent : (null)

   +0x0b4 NeedToZeroVacb   : (null)

   +0x0b8 BcbSpinLock      : 0

   +0x0bc Reserved         : (null)

   +0x0c0 Event            : _KEVENT

   +0x0d0 VacbPushLock     : _EX_PUSH_LOCK

   +0x0d8 PrivateCacheMap  : _PRIVATE_CACHE_MAP


저작자 표시 비영리
Write your message and submit

안녕하세요 올엠 입니다.

오늘은 Windows Update 리스트를 생성해 주는 Getupdate에 대해 알려드리겠습니다.

뭐.. 제가 만든건 아니구, 필요해 의해 찾게 되었습니다.

우선 만들어주신 개발자 분에게 감사의 말을 전합니다.(외국인 이므로, 영어로 해야하나.. ;;)

일반적으로는, 업데이트 리스트를 저장할 필요가 없지만, 서버 관리자의 경우는 다르겠죠, 각서버의 업데이트 상태등을 확인하기 위해 본 스크립트는 유용할수 있어요.
GetUpdate는 VB 스크립트로 실행하면, 윈도우와 관련된 설치된 패치들을 HTML 파일로 생성하여 나열하게 됩니다.


그렇다면 본 스크립트는 어떤 원리로 작동하는 것일까요?

내용을 보면 WMI의 쿼리를 사용하여 인스톨된 업데이트 리스트를 생성하도록 되어 있습니다. (내용이 길지도 않습니다.)
Set QFEs = objWMIService.ExecQuery ("Select * from win32_QuickFixEngineering")

위 문장으로 Windows 관련 패치내용을 수집합니다.

그리고 나열은
QFE를 사용하여, For를 사용하여 QFE로 QFEs를 넣고 if문으로 하나씩 나누어 줄을 찍도록 합니다.
For Each QFE in QFEs

여기서 나열시 링크를 만들수 있었던건, MS는 핫픽스 번호와 웹링크가 일치한다는것을 이용하여,
    "<TD> <a href=""http://support.microsoft.com/?kbid=" & getKBID(QFE.HotFixID) & """>" & getKBID(QFE.HotFixID) & "</a></TD>" &_  
위 문장으로 웹링크를 같이 자동적으로 생성해준다는 것이죠.
그런데 getKBID(QFE.HotFixID)라는 함수로 값을 가져가도로고되어 있죠?
그전에 아래 작업을 먼저 진행하여, 링크 오류를 없애 주기 위해서 입니다.

일부 패치 HotFixID의 경우 KB 웹문서로 만들어 지지 않았을 수 있죠, 바로 Q, M또는 아예 번호가 없는 경우
 이에 대한 수정을 할 필요가 있겠죠. 이작업을 진행해 주는것이 바로 아래 문장들 입니다.
 Dim KBNumber
 KBNumber = right(HotFixID,6)
 if isNumeric(KBNumber) then
  getKBID = KBNumber
 else
  getKBID = "No KB Number Found"
 end if
end function


KBNumber 함수에 HotFIxID 값을 확인하는데, 6자리의 값만을 가져오도록 함수를 수정후
만약  KBNumber 이 값이 숫자라면,로 getKBID값으로 넣게 되며, 숫자가 아니면, No KB Number Found의 값을 getKBID로 넣게 됩니다.

본 스크립트를 실행한 결과는 아래와 같습니다.

저작자 표시 비영리
Write your message and submit

Netsh DHCP server scope Network_Address delete lease allbadaddresses

 

예)

10.1.2.0 네트워크의 Badaddresses삭제

 

 

Netsh dhcp server scope 10.1.2.0 delete lease allbadaddresses

 

이렇게 .bat를 만들어 예약 작업에 넣어두고 실행해보자

 

그럼 자동으로 삭제가 된다

Write your message and submit

시스템 정보 GetVersionEx

Posted 2009/08/14 16:42

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);                                          

HINSTANCE g_hInst;      

LPCTSTR IpszClass=TEXT("MessageBox");

 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR IpszCmdParam,int nCmdShow)   

 

{                                                                                                                                                                                                                                                                        

 

           HWND hWnd;

           MSG Message;

 

           WNDCLASS WndClass;

           g_hInst=hInstance;

 

           WndClass.cbClsExtra=0;

           WndClass.cbWndExtra=0;

           WndClass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);

           WndClass.hCursor=LoadCursor(NULL,IDC_NO);

           WndClass.hIcon=LoadIcon(NULL,IDI_QUESTION);

           WndClass.hInstance=hInstance;

           WndClass.lpfnWndProc=WndProc;

           WndClass.lpszClassName=IpszClass;

           WndClass.lpszMenuName=NULL;

           WndClass.style=CS_HREDRAW|CS_VREDRAW;

           RegisterClass(&WndClass);

 

           hWnd=CreateWindow(IpszClass,TEXT("My First Program"),WS_OVERLAPPEDWINDOW,300,100,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

           ShowWindow(hWnd,nCmdShow);

 

                     while (GetMessage(&Message,NULL,0,0)){

                                TranslateMessage(&Message);

                     DispatchMessage(&Message);

 

           }

           return (int)Message.wParam;       

}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

           HDC hdc;

           PAINTSTRUCT ps;

           OSVERSIONINFO osv;

           TCHAR str[255];

           TCHAR Plat[255];

 

           switch (iMessage) {

                     case WM_PAINT:

                                hdc=BeginPaint(hWnd,&ps);

                                osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);

                                GetVersionEx(&osv);

                                wsprintf(str,"운영체제 버전 = %d.%d, 빌더 넘버=%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);

                                TextOut(hdc,50,50,str,lstrlen(str));

                                switch (osv,dwPlatformld) {

                     case VER_PLATFORM_WIN32s:

                                lstrcpy(Plat,"윈도우즈 3.1 Win32s");

                                break;

                     case VER_PLATFORM_WIN32_WINDOWS:

                                lstrcpy(Plat,"윈도우즈 95/98");

                                break;

                     case VER_PLATFORM_WIN32_NT:

                                lstrcpy(Plat,"윈도우즈 NT,2000");

                                break;

                                }

                                wsprintf(str,"플랫폼=%s, 서비스팩=%s",Plat,osv.szCSDVersion);

                                TextOut(hdc,50,70,str,lstrlen(str));

                                EndPaint(hWnd, &ps);

                                return 0;

                     case WM_DESTROY:

                                PostQuitMessage(0);

                                return 0;

           }

           return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);

 

조사된 버전 정보를 OSVERSIONINFO(EX)라는 구조체에 리턴하라는 구조체 인데, 함수호출전에sizeof(OSVERSIONINFO)값을 대입해 두면 이전 구조체 멤버만 조사하고 EX구조체의 크기를 대입해 두면 확장된 구조체의 모든 정보를 조사하게 됩니다.

 

이 구조체의 많은 선언된 값중 dwPlatformId는 운영체제의 계열을 나타내는 값으로 다음 3가지 값을 같습니다. ( 더 증가 했을 수도 있어요)

 

VER_PLATFORM_WIN32S 윈도우 3.1에서 실행되는 Win32s

VER_PLATFORM_WIN32_WINDOWS 윈도우 95/98

VER_PLATFORM_WIN32_NT 윈도우 NT/2000


저작자 표시 비영리

'프로그래밍 > C/C++' 카테고리의 다른 글

Duplicate symbol warning시 확인해야 하는 부분  (0) 2010/04/01
시스템 정보 GetVersionEx  (0) 2009/08/14
시스템 정보 GetComputerName  (0) 2009/08/14
시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
Write your message and submit

시스템 정보 GetComputerName

Posted 2009/08/14 15:40

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);                                          

HINSTANCE g_hInst;      

LPCTSTR IpszClass=TEXT("MessageBox");

 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR IpszCmdParam,int nCmdShow)   

 

{                                                                                                                                                                                                                                                                        

 

           HWND hWnd;

           MSG Message;

 

           WNDCLASS WndClass;

           g_hInst=hInstance;

 

           WndClass.cbClsExtra=0;

           WndClass.cbWndExtra=0;

           WndClass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);

           WndClass.hCursor=LoadCursor(NULL,IDC_NO);

           WndClass.hIcon=LoadIcon(NULL,IDI_QUESTION);

           WndClass.hInstance=hInstance;

           WndClass.lpfnWndProc=WndProc;

           WndClass.lpszClassName=IpszClass;

           WndClass.lpszMenuName=NULL;

           WndClass.style=CS_HREDRAW|CS_VREDRAW;

           RegisterClass(&WndClass);

 

           hWnd=CreateWindow(IpszClass,TEXT("My First Program"),WS_OVERLAPPEDWINDOW,300,100,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

           ShowWindow(hWnd,nCmdShow);

 

                     while (GetMessage(&Message,NULL,0,0)){

                                TranslateMessage(&Message);

                     DispatchMessage(&Message);

 

           }

           return (int)Message.wParam;       

}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

           TCHAR szComName[255];

           TCHAR szUserName[255];

           TCHAR str[255];

           DWORD len;

           HDC hdc;

           PAINTSTRUCT ps;

 

           switch (iMessage){

                     case WM_PAINT:

                                hdc=BeginPaint(hWnd, &ps);

                                len=255;

                                GetComputerName(szComName,&len);

                                len=255;

                                GetUserName(szUserName,&len);

                                wsprintf(str,"컴퓨터 이름=%s, 사용자 이름=%s",szComName,szUserName);

                                TextOut(hdc,50,50,str,lstrlen(str));

                                EndPaint(hWnd,&ps);

                                return 0;

                     case WM_DESTROY:

                                PostQuitMessage(0);

                                return 0;

           }

           return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

 

VOID GetComputerName(LPTSTR lpBuffer, LPDWORD lpnSize);
int GetUserName(LPTSTR lpBuffer);


두함수 모두 이름을 리턴 받기 위한 버퍼의 주소를 첫번째 인수로 넘겨주고 두 번째 인수에서 이 버퍼의 길이를 담을 정수형 변수를 넘겨주는 방식

버퍼의 길이를 예제와 같이 255로 충분히 잡아줘서 원칙적으로 NULL값을 전달하여 필요한 길이를 조사후 메모리를 할당하는 2번 호출하는 번거로움을 줄이도록 하자

 

저작자 표시 비영리

'프로그래밍 > C/C++' 카테고리의 다른 글

Duplicate symbol warning시 확인해야 하는 부분  (0) 2010/04/01
시스템 정보 GetVersionEx  (0) 2009/08/14
시스템 정보 GetComputerName  (0) 2009/08/14
시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
Write your message and submit

시스템 정보 GetSystemInfo

Posted 2009/08/14 15:39

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);                                          

HINSTANCE g_hInst;      

LPCTSTR IpszClass=TEXT("MessageBox");

 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR IpszCmdParam,int nCmdShow)   

 

{                                                                                                                                                                                                                                                                        

 

           HWND hWnd;

           MSG Message;

 

           WNDCLASS WndClass;

           g_hInst=hInstance;

 

           WndClass.cbClsExtra=0;

           WndClass.cbWndExtra=0;

           WndClass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);

           WndClass.hCursor=LoadCursor(NULL,IDC_NO);

           WndClass.hIcon=LoadIcon(NULL,IDI_QUESTION);

           WndClass.hInstance=hInstance;

           WndClass.lpfnWndProc=WndProc;

           WndClass.lpszClassName=IpszClass;

           WndClass.lpszMenuName=NULL;

           WndClass.style=CS_HREDRAW|CS_VREDRAW;

           RegisterClass(&WndClass);

 

           hWnd=CreateWindow(IpszClass,TEXT("My First Program"),WS_OVERLAPPEDWINDOW,300,100,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

           ShowWindow(hWnd,nCmdShow);

 

                     while (GetMessage(&Message,NULL,0,0)){

                                TranslateMessage(&Message);

                     DispatchMessage(&Message);

 

           }

           return (int)Message.wParam;       

}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

           HDC hdc;

           PAINTSTRUCT ps;

           SYSTEM_INFO si;

           TCHAR str[128];

           TCHAR Arch[100], Level[100];

           TCHAR KeyType[100];

           static int arFunc[]={0,10,12,10,12,10,24,7,8,9,10,11,12};

 

           switch (iMessage) {

                     case WM_PAINT:

                                hdc=BeginPaint(hWnd, &ps);

                                GetSystemInfo(&si);

                                wsprintf(str, "프로세서의 개수는 %d개 입니다", si.dwNumberOfProcessors);

                                TextOut(hdc,10,10,str,lstrlen(str));

                                switch (si.wProcessorArchitecture) {

                     case PROCESSOR_ARCHITECTURE_INTEL:lstrcpy(Arch, "Intel");break;

                     case PROCESSOR_ARCHITECTURE_MIPS:lstrcpy(Arch, "MIPS");break;

                     case PROCESSOR_ARCHITECTURE_ALPHA:lstrcpy(Arch, "Alpha");break;

                     case PROCESSOR_ARCHITECTURE_PPC:lstrcpy(Arch, "Power PC");break;

                     case PROCESSOR_ARCHITECTURE_UNKNOWN:lstrcpy(Arch, "알수없음");break;

                                }

                                switch (si.wProcessorLevel){

                     case 3:lstrcpy(Level,"80386");break;

                     case 4:lstrcpy(Level,"80386");break;

                     case 5:lstrcpy(Level,"Pentium");break;

                     case 6:lstrcpy(Level,"Pentium Pro or Pentium II");break;

                     default:lstrcpy(Level,"기타");break;

                                }

                                wsprintf(str, "CPU 종류는 %s이며 레벨은 %s, 리비전은 %x입니다.", Arch, Level, si.wProcessorRevision);

                                TextOut(hdc,10,30,str,lstrlen(str));

 

                                switch (GetKeyboardType(0)) {

                     case 1:lstrcpy(KeyType,"IBM PC/XT or compatible(83 key)");break;

                     case 2:lstrcpy(KeyType,"Olivetti ICO(102 key)");break;

                     case 3:lstrcpy(KeyType,"IBM PC/AT (84 key)");break;

                     case 4:lstrcpy(KeyType,"IBM enhanced(101 or 102 key)");break;

                     case 5:lstrcpy(KeyType,"Nokia 1050");break;

                     case 6:lstrcpy(KeyType,"Nokia 9140");break;

                     case 7:lstrcpy(KeyType,"일본 키보드");break;

                     default:lstrcpy(KeyType,"기타 키보드");break;

                                }

                                wsprintf(str,"키보드 타입은 %s이며 서브 타입은 %d, 펑션키는 %d개입니다.",KeyType, GetKeyboardType(1), arFunc[GetKeyboardType(2)]);

                                TextOut(hdc,10,50,str,lstrlen(str));

                                EndPaint(hWnd,&ps);

                                return 0;

                     case WM_DESTROY:

                                PostQuitMessage(0);

                                return 0;

           }

           return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);

이 함수는 시스템의 구성 정보를 조사하여 인수로 전달된 구조체에 채워 리턴하는 출력용 구조체 이다.

int GetKeyboardType(int nTypeFlag);

nTypeFlag에 0을 주면 키보드 종류를 1을 주면 서브타입을 2를 주면 펑션키의 개수를 조사함

저작자 표시 비영리

'프로그래밍 > C/C++' 카테고리의 다른 글

시스템 정보 GetVersionEx  (0) 2009/08/14
시스템 정보 GetComputerName  (0) 2009/08/14
시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
입력문 WM_KEYDOWN  (0) 2009/08/14
Write your message and submit

메타파일 CreateEnhMetaFile

Posted 2009/08/14 15:38

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM IParam)

{

           HDC hdc;

           HDC hdcMeta;

           HENHMETAFILE hMFile;

           RECT rt;

           switch (iMessage){

                     case WM_LBUTTONDOWN:

                                hdc=GetDC(hWnd);

                                hdcMeta=CreateEnhMetaFile(hdc,"TestEnh.emf",NULL,"My Program\0Test Enh Meta File\0");

                                Ellipse(hdcMeta,10,10,100,100);

                                Rectangle(hdcMeta,5,105,105,120);

                                hMFile=CloseEnhMetaFile(hdcMeta);

                                DeleteEnhMetaFile(hMFile);

                                ReleaseDC(hWnd,hdc);

                                MessageBox(hWnd,"Meta File Created","Meta",MB_OK);

                                return 0;

                     case WM_RBUTTONDOWN:

                                hdc=GetDC(hWnd);

                                hMFile=GetEnhMetaFile("TestEnh.emf");

                                if(hMFile == NULL) {

                                          MessageBox(hWnd,"File Not Found","Meta",MB_OK);

                                }else{

                                          rt.left=LOWORD(lParam);

                                          rt.right=rt.left+100;

                                          rt.top=HIWORD(lParam);

                                          rt.bottom=rt.top+100;

                                          PlayEnhMetaFile(hdc,hMFile,&rt);

                                }

                                DeleteEnhMetaFile(hMFile);

                                ReleaseDC(hWnd,hdc);

                                return 0;

                     case WM_DESTROY:

                                PostQuitMessage(0);

                                return 0;

           }

                     return(DefWindowProc(hWnd,iMessage,wParam,IParam));

}


HDC CreateEnhMetaFile(HDC hdcRef, LPCTSTR lpFilename, CONST RECT *lpRect, LPCTSTR lpDescription);

hdcRef
메타 DC를 만들 때 참조하는 DC로 해상도와 사용 단위를 참고해 메타 DC를 만드는데 NULL로 지정하면 사용중인 디스플레이의 DC를 참조하게 된다

lpFileName
만들어질 메타 파일 이름

lpRect
메타 파일 크기지정 (0,01mm단위) NULL로 지정하면 GDI는 그림 전체를 포함한 크기를 계산하여 사용

lpDescription
메타파일에 설명을 문자열로 기입할수 있음, NULL지정가능

저작자 표시 비영리

'프로그래밍 > C/C++' 카테고리의 다른 글

시스템 정보 GetComputerName  (0) 2009/08/14
시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
입력문 WM_KEYDOWN  (0) 2009/08/14
화면 재생성 InvalidateRect  (0) 2009/08/14
Write your message and submit

입력문 MOUSE

Posted 2009/08/14 15:36


#include <windows.h> //기본적인 데이터 타입, 함수 원형, 매크로 상수 등을 정의하며 그외 윈도우즈 프로그래밍에 필요한 보조 헤더 파일을 포함

 

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //사용자와 시스템이 보내오는 메세지를 처리하는 아주 중요한 일을 하는 WInMain외 나머지 하나 시작점

                                                    //CALLBACK 메크로는 _stdcall로 정의됨

HINSTANCE g_hInst;    //HINSTANCE에 전역변수 g_hInst지정

LPCTSTR IpszClass=TEXT("MessageBox"); //IpszClass라는 전역 문자열 정의

 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR IpszCmdParam,int nCmdShow)    

    //프로그램의 시작점인 엔트리 포인트(Entry Point)

    //hInstance 프로그램의 인스턴스 핸들

    //hPrevInstance 바로 앞에 실행된 현재 프로그램의 인스턴스 핸들

    //IpszCmdParam 명령행으로 입력된 프로그램 인수

    //nCmdShow 프로그램이 실행될 형태이며 최소화, 보통 모양

{                                                                                                    

 

    HWND hWnd;

    MSG Message; //어떤 종류의 메시지인가를 나타냄

    //tagMSG

    // hwnd : 메시지를 받을 윈도우 핸들

    // message : 어떤 종류의 메세지 인지 나타내는 값

    // wParam : 전달된 메시지에 대한 부가적인 정보를 가짐

    // IParam : 전달된 메시지에 대한 보가적 정보를 가짐

    // time : 메시지 발생 시간

    // pt : 메시지가 발생할시 마우스 위치

    WNDCLASS WndClass; // 클래스 종류 지정

    g_hInst=hInstance;

 

    WndClass.cbClsExtra=0; //예약 영역

    WndClass.cbWndExtra=0; //예약 영역+

    WndClass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH); //배경 색상지정

    WndClass.hCursor=LoadCursor(NULL,IDC_NO); //사용할 마우스 커서 지정

    WndClass.hIcon=LoadIcon(NULL,IDI_QUESTION); //사용할 아이콘 지정

    WndClass.hInstance=hInstance; //등록하는 프로그램 번호 hInstance 값을 그대로 대임함

    WndClass.lpfnWndProc=WndProc; //윈도우의 메시지 처리 함수 지정

    WndClass.lpszClassName=IpszClass; //윈도우 클래스의 이름을 문자열로 지정, 여기서 지정한 이름 이 CreateWindow함수에 전달됨

    WndClass.lpszMenuName=NULL; //사용할 메뉴를 지정, 메뉴는 프로그램 코드에서 실행중에 만드는 것이 아니라 리소스 에디터에 의해 별도로 만들어짐

    WndClass.style=CS_HREDRAW|CS_VREDRAW; //윈도위우의 스타일 지정

    RegisterClass(&WndClass); //WNDCLASS 구조체의 번지를 전달

 

    hWnd=CreateWindow(IpszClass,TEXT("My First Program"),WS_OVERLAPPEDWINDOW,300,100,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow);

    // IpszClassName 생성하고자 하는 윈도우의 클래스를 지정하는 문자열

    // IpszWindowsName 윈도우 타이틀바에 나타날 문자열

    // dwStyle 만들고자 하는 윈도우의 형태를 지정하는 인수

    // X, Y, nWidth, nHeight 윈도우의 크기와 위치를 지정하며 픽셀 단위를 사용함

    // hWndParent 부모 윈도우가 있을 경우 부모 윈도우의 핸들을 지정

    // hmenu 윈도우에서 사용할 메뉴의 핸들을 지정

    // hinst 프로그램의 핸들을 지정 WinMain의 인수로 전달된 hInstance를 대입

    // IpvParam CREATESTRUCT라는 구조체의 번지이며 여러개의 윈도우를 만들때 각 윈도우에 고유의 파라미터를 전달하는 특수한 목적에 사용

    // BOOL ShowWindow(hWnd, nCmdShow); hWnd 인수는 화면으로 출력하고자 하는 윈도우의 핸들이며 CreateWindow 함수가 리턴한 핸들을 그대로 넘기면됨,

    // nCmdShow는 윈도우를 화면에 출력하는 방법을 지정하며 다음 매크로를 상수들이 정의되어 있음

    // SW_HIDE 윈도움 숨김

    // SW_MINIMIZE 윈도우를 최소화

    // SW_RESTORE 윈도우를 활성화

    // SW_SHOW 윈도우를 활성화하여 보여줌

    // SW_SHOWNORMAL 윈도우를 활성화하여 보여줌

        while (GetMessage(&Message,NULL,0,0)){ //메시지 큐에서 메시지를 읽어들임, 메시지 큐는 시스템이나 사용자로 부터 발생하는 메시지가 임시 저장하는 영역

        TranslateMessage(&Message); //키보드의 입력 메세지를 가공하여 프로그램에서 쉽게 쓸 수 있도록 함

        DispatchMessage(&Message); //메시지 큐에서 꺼낸 메시지를 윈도우의 메시지 처리 함수로 전달

    // 메세지 루프

    }

    return (int)Message.wParam;    // 메세지 루프가 종료 될때 Message.wParam을 리턴하고 종료됨

}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM IParam)

{

    HDC hdc;

    PAINTSTRUCT ps;

    static int x;

    static int y;

    static BOOL bNowDraw=FALSE;

    

    switch (iMessage){

        case WM_LBUTTONDOWN:    //좌측 버튼이 눌려졌을 때

            x=LOWORD(IParam);    // 마우스 x좌표의 위치 기억

            y=HIWORD(IParam);    // 마우스 y좌표의 위치 기억

            bNowDraw=TRUE;    //그리기가 됨

            return 0;

        case WM_MOUSEMOVE:    //마우스가 움직일 때

            if(bNowDraw==TRUE) {    //만약 그리는 중이면 아래 내용 실행

                hdc=GetDC(hWnd);    //DC 핸들을 발급 받음

                MoveToEx(hdc,x,y,NULL);    //LineTO 위치까지 선을 긋기위한 시작점

                x=LOWORD(IParam);    // 마우스 x좌표의 새위치 기억

                y=HIWORD(IParam);    // 마우스 y좌표의 새위치 기억

                LineTo(hdc,x,y);    //해당 좌표로 이동

                ReleaseDC(hWnd,hdc);

            }

            return 0;

        case WM_LBUTTONUP:    //좌측 버튼이 올라왔을 때

            bNowDraw=FALSE;    //그리기를 않함

            return 0;

        case WM_DESTROY:

            PostQuitMessage(0);

            return 0;

    }

        return(DefWindowProc(hWnd,iMessage,wParam,IParam)); //WndProc에서 처리하지 않은 나머지 메시지에 관한 처리

}

더블 클릭으로 마우스로 그린 그림을 지우기
*주의
더블클릭 이벤트를 미리 윈도우 스타일에 지정해 주어야 사용 가능하다.

#include <windows.h> //기본적인 데이터 타입, 함수 원형, 매크로 상수 등을 정의하며 그외 윈도우즈 프로그래밍에 필요한 보조 헤더 파일을 포함

 

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //사용자와 시스템이 보내오는 메세지를 처리하는 아주 중요한 일을 하는 WInMain외 나머지 하나 시작점

                                                    //CALLBACK 메크로는 _stdcall로 정의됨

HINSTANCE g_hInst;    //HINSTANCE에 전역변수 g_hInst지정

LPCTSTR IpszClass=TEXT("MessageBox"); //IpszClass라는 전역 문자열 정의

 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR IpszCmdParam,int nCmdShow)    

    //프로그램의 시작점인 엔트리 포인트(Entry Point)

    //hInstance 프로그램의 인스턴스 핸들

    //hPrevInstance 바로 앞에 실행된 현재 프로그램의 인스턴스 핸들

    //IpszCmdParam 명령행으로 입력된 프로그램 인수

    //nCmdShow 프로그램이 실행될 형태이며 최소화, 보통 모양

{                                                                                                    

 

    HWND hWnd;

    MSG Message; //어떤 종류의 메시지인가를 나타냄

    //tagMSG

    // hwnd : 메시지를 받을 윈도우 핸들

    // message : 어떤 종류의 메세지 인지 나타내는 값

    // wParam : 전달된 메시지에 대한 부가적인 정보를 가짐

    // IParam : 전달된 메시지에 대한 보가적 정보를 가짐

    // time : 메시지 발생 시간

    // pt : 메시지가 발생할시 마우스 위치

    WNDCLASS WndClass; // 클래스 종류 지정

    g_hInst=hInstance;

 

    WndClass.cbClsExtra=0; //예약 영역

    WndClass.cbWndExtra=0; //예약 영역+

    WndClass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH); //배경 색상지정

    WndClass.hCursor=LoadCursor(NULL,IDC_NO); //사용할 마우스 커서 지정

    WndClass.hIcon=LoadIcon(NULL,IDI_QUESTION); //사용할 아이콘 지정

    WndClass.hInstance=hInstance; //등록하는 프로그램 번호 hInstance 값을 그대로 대임함

    WndClass.lpfnWndProc=WndProc; //윈도우의 메시지 처리 함수 지정

    WndClass.lpszClassName=IpszClass; //윈도우 클래스의 이름을 문자열로 지정, 여기서 지정한 이름 이 CreateWindow함수에 전달됨

    WndClass.lpszMenuName=NULL; //사용할 메뉴를 지정, 메뉴는 프로그램 코드에서 실행중에 만드는 것이 아니라 리소스 에디터에 의해 별도로 만들어짐

    WndClass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; //윈도우의 스타일 지정, 더블클릭 이벤트를 사용하겠다는 정의를 미리 해주어야 한다.

    RegisterClass(&WndClass); //WNDCLASS 구조체의 번지를 전달

 

    hWnd=CreateWindow(IpszClass,TEXT("My First Program"),WS_OVERLAPPEDWINDOW,300,100,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow);

    // IpszClassName 생성하고자 하는 윈도우의 클래스를 지정하는 문자열

    // IpszWindowsName 윈도우 타이틀바에 나타날 문자열

    // dwStyle 만들고자 하는 윈도우의 형태를 지정하는 인수

    // X, Y, nWidth, nHeight 윈도우의 크기와 위치를 지정하며 픽셀 단위를 사용함

    // hWndParent 부모 윈도우가 있을 경우 부모 윈도우의 핸들을 지정

    // hmenu 윈도우에서 사용할 메뉴의 핸들을 지정

    // hinst 프로그램의 핸들을 지정 WinMain의 인수로 전달된 hInstance를 대입

    // IpvParam CREATESTRUCT라는 구조체의 번지이며 여러개의 윈도우를 만들때 각 윈도우에 고유의 파라미터를 전달하는 특수한 목적에 사용

    // BOOL ShowWindow(hWnd, nCmdShow); hWnd 인수는 화면으로 출력하고자 하는 윈도우의 핸들이며 CreateWindow 함수가 리턴한 핸들을 그대로 넘기면됨,

    // nCmdShow는 윈도우를 화면에 출력하는 방법을 지정하며 다음 매크로를 상수들이 정의되어 있음

    // SW_HIDE 윈도움 숨김

    // SW_MINIMIZE 윈도우를 최소화

    // SW_RESTORE 윈도우를 활성화

    // SW_SHOW 윈도우를 활성화하여 보여줌

    // SW_SHOWNORMAL 윈도우를 활성화하여 보여줌

        while (GetMessage(&Message,NULL,0,0)){ //메시지 큐에서 메시지를 읽어들임, 메시지 큐는 시스템이나 사용자로 부터 발생하는 메시지가 임시 저장하는 영역

        TranslateMessage(&Message); //키보드의 입력 메세지를 가공하여 프로그램에서 쉽게 쓸 수 있도록 함

        DispatchMessage(&Message); //메시지 큐에서 꺼낸 메시지를 윈도우의 메시지 처리 함수로 전달

    // 메세지 루프

    }

    return (int)Message.wParam;    // 메세지 루프가 종료 될때 Message.wParam을 리턴하고 종료됨

}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM IParam)

{

    HDC hdc;

    PAINTSTRUCT ps;

    static int x;

    static int y;

    static BOOL bNowDraw=FALSE;

    

    switch (iMessage){

        case WM_LBUTTONDOWN:

            x=LOWORD(IParam);

            y=HIWORD(IParam);

            bNowDraw=TRUE;

            return 0;

        case WM_MOUSEMOVE:

            if(bNowDraw==TRUE) {

                hdc=GetDC(hWnd);

                MoveToEx(hdc,x,y,NULL);

                x=LOWORD(IParam);

                y=HIWORD(IParam);

                LineTo(hdc,x,y);

                ReleaseDC(hWnd,hdc);

            }

            return 0;

        case WM_LBUTTONUP:

            bNowDraw=FALSE;

            return 0;

        case WM_LBUTTONDBLCLK:    //더블 클릭 하였을 때

            InvalidateRect(hWnd, NULL, TRUE);    //작업영역을 무효화

            return 0;

        case WM_DESTROY:

            PostQuitMessage(0);

            return 0;

    }

        return(DefWindowProc(hWnd,iMessage,wParam,IParam)); //WndProc에서 처리하지 않은 나머지 메시지에 관한 처리

}

'프로그래밍 > C/C++' 카테고리의 다른 글

시스템 정보 GetSystemInfo  (0) 2009/08/14
메타파일 CreateEnhMetaFile  (0) 2009/08/14
입력문 MOUSE  (0) 2009/08/14
입력문 WM_KEYDOWN  (0) 2009/08/14
화면 재생성 InvalidateRect  (0) 2009/08/14
입력문 WM_CHAR  (0) 2009/08/14
Write your message and submit