C# winapi call

프로그래밍/C# 2012. 10. 18. 22:25

아래 사이트에서 api 함수 검색

http://www.pinvoke.net/index.aspx

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

C# winapi call  (0) 2012.10.18
Panel에 DoubleBuffering 적용하기  (0) 2011.12.27
c# 설정 저장  (0) 2011.12.26
c# 에서 InputBox 사용하기  (1) 2011.12.07
닷넷 프레임워크 기반의 소켓 프로그래밍 가이드  (2) 2011.11.16
.Net의 기초  (0) 2011.11.01
Posted by la Mancha
TAG c#, winapi

댓글을 달아 주세요

부트 과정

BIOS 사전 부트

 구성 요소

프로세서 실행 

기능 

위치 

Master Boot Record 

Real Mode 

파티션 부트 섹터를 읽고 로드 한다. 

각 저장 장치 

Boot Sector 

Real Mode 

Bootmgr을 로드하기 위해 루트 디렉터리를 읽는다. 

각 파티션 

Bootmgr

리얼 모드 & 페이징 없는 32비트

부트 구성 DB를 읽어 부트 메뉴를 보여주고 메모리 테스트 애플리케이션 같은 사전 부트 프로그램을 실행한다. 64bit 설치로 부팅되면 Winload를 로딩하기 전에 64bit 롱모드로 전환한다. 

각 시스템 

 Winload.exe

페이징 32비트 보호 모드, Win64 설치 부팅이라면 64비트 보호 모드

Ntoskrnl.exe 관련 모듈을 로드하고 부트 시작 디바이스 드라이버를 로드한다. 

각 윈도우 설치 

Ntoskrnl.exe 

페이징 보호 모드  

익스큐티브 서브시스템이나 부트와 부트 시작 디바이스 드라이버를 초기화하고, 네이티브 애플리케이션을 실행하기 위한 시스템을 준비하고 Smss.exe 를 실행한다. 

각 윈도우 설치 

Smss.exe 

네이티브 애플리케이션 

초기 인스턴스는 자기 자신을 복사해 각 세션을 초기화한다. 세션 0 인스턴스는 윈도우 서브시스템 드라이버(Win32k.sys)를 로드하고 윈도우 서브시스템 프로세스나(Csrss.exe)나 윈도우 초기화 프로세스(WinInit.exe)를 시작한다. 그 밖의 모든 세션 인스턴스는 Csrss와 Winlogon 프로세스를 시작한다. 

각 윈도우 설치 


물리 디스크는 섹터 단위로 구성되며 BIOS PC에서 HDD 섹터는 일반적으로 512바이트다. 윈도우 설치 프로그램처럼 하드디스크에 볼륨을 정의하는 유틸리티는 하드디스크의 첫 섹터에 마스터 부트 레코드라는 데이터 섹터를 기록한다. 


MBR은 실행 명령(부트 코드)과 디스크상에 주 파티션 위치를 지정하는 4개의 항목을 가진 테이블(파티션 테이블)이 있는 고정된 양의 공간이다. BIOS 기반 컴퓨터가 부팅될 때 MBR 을 실행하는 첫 번째 코드는 ROM에 기록되어 있다. BIOS는 부트 장치를 선택해 장치의 MBR을 메모리로 읽어 MBR에 있는 코드에 제어를 전달한다. 


MBR은 

1. 주 파티션을 검사해 부팅할 수 있는 플래그가 들어있는 파티션을 찾는다. 

2. 최소 하나 이상의 플래그를 찾으면 플래그가 있는 파티션에서 첫 번째 섹터를 메모리로 읽고 파티션에 포함된 코드로 제어를 전달한다. 이러한 유형의 파티션을 시스템 파티션이라 하고, 시스템 파티션의 첫 섹터를 부트 섹터라고 한다. 시스템 파티션이 정의된 볼륨을 시스템 볼륨이라고 한다. 


BIOS 부트 섹터와 Bootmgr

부트 섹터 코드의 역할은 볼륨의 구조와 포맷에 관한 윈도우 정보를 얻고, 볼륨 루트 디렉터리에서 Bootmgr 파일을 읽는 것이다. 부트 섹터 코드는 Bootmgr 을 메모리로 로드한 후 Bootmgr의 진입점에 제어를 넘긴다. 


Bootmgr은 시스템이 리얼 모드라는 x86 동작 모드로 실행하는 동안 존재한다. 

리얼모드에서의 메모리 주소는 가상 주소에 대한 물리 주소 변환이 일어나지 않는다. 이는 메모리 주소를 사용하는 프로그램이 물리적인 주소로서 해석한다는 것과, 컴퓨터의 물리적 메모리에서 첫 1MB 만 접근 가능하다는 의미다. 

Bootmgr이 수행하는 첫 번째 작업은 시스템을 보호 모드로 전환하는 것이다. 이 시점에서는 가상 주소에 대한 물리 주소 변환이 발생하지 않지만 모든 32비트 메모리는 접근 가능하다.

시스템이 보호 모드로 진입한 후 Bootmgr은 물리적 메모리에 접근 가능하다. 페이징 활성화로 16MB 이하 메모리에 접근할 수 있는 충분한 페이지 테이블을 생성한 후에 Bootmgr은 페이징을 할 수 있다. 윈도우가 일반적인 동작을 수행하는 모드는 페이징을 사용할 수 있는 보호 모드다. 





'프로그래밍 > Windows' 카테고리의 다른 글

Windows boot process  (0) 2012.07.13
write MBR windows 7  (3) 2012.06.27
Posted by la Mancha

댓글을 달아 주세요

MBR 을 00000000 ... 으로 초기화 시키는 코드 실행하고 컴퓨터를 다시 킬 경우 아래와 같은 창을 볼 수 있으며 부팅이 되지 않는다. 

#include <stdio.h>

#include <windows.h>

#pragma pack(1)

typedef struct _DOS_PARTITION_STRUCT {

unsigned char    IsBootable; // 부트 가능하면 0x80, 부트 불가능하면 0x00

    unsigned char    CHSOffset[3]; // CHS(Cylinder-Head-Sector)로 표현되는 실제 파티션 주소

    unsigned char    PartitionType; // 파티션 유형 (ex: FAT32=0x0C, NTFS=0x07, ...)

    unsigned char    EndCHSOffset[3]; // CHS 주소로 표현되는 파티션의 끝 지점

    unsigned long    LBAOffset; // LBA(Logical Block Addressing)로 표현되는 파티션 주소

    unsigned long    SizeInSector; // 파티션이 사용하는 섹터(LBA)의 총 개수

} DOS_PARTITION_STRUCT, *PDOS_PARTITION_STRUCT;

#pragma pack()

#define MBR_PartitionTableOffset 0x1BEL

int main(void)

{

 HANDLE hPhysicalDrive = NULL;

 LONG   highPos    = 0;

 BYTE   MasterBootRecord[512] = {0};

 DWORD  lBytesRead   = 0;

 hPhysicalDrive = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

 if(hPhysicalDrive == INVALID_HANDLE_VALUE)

 {

  printf("[!] Disk Open Error! (LastErr=0x%08lX)\n", GetLastError ());

  return 1L;

 }

 SetFilePointer(hPhysicalDrive, 0L, &highPos, FILE_BEGIN); // 사실상 이 부분은 하지 않아도 된다.

WriteFile(hPhysicalDrive, MasterBootRecord, 512, &lBytesRead, NULL);

 CloseHandle(hPhysicalDrive);

 return 0L;

}

'프로그래밍 > Windows' 카테고리의 다른 글

Windows boot process  (0) 2012.07.13
write MBR windows 7  (3) 2012.06.27
Posted by la Mancha

댓글을 달아 주세요

  1. skensita 2012.11.15 14:40 신고  댓글주소  수정/삭제  댓글쓰기

    꼭 Windows가 설치된 Disk가 0번이라고 볼수는 없습니다.

    아래의 함수를 사용하면 Windows가 설치된 Disk를 정확하게 가져올 수 있습니다.


    UINT32 GetSystemDiskNumber()
    {
    DWORD dwDiskNumber = (DWORD)-1;
    VOLUME_DISK_EXTENTS volExt;
    DWORD requiredSize = sizeof(VOLUME_DISK_EXTENTS)<<1;
    TCHAR szDrive[] = _T("\\\\.\\C:");

    TCHAR szPath[MAX_PATH];
    ::SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, szPath);
    szDrive[4] = szPath[0];

    HANDLE hDrive = ::CreateFile( szDrive, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );

    if(DeviceIoControl( hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, &volExt, sizeof(volExt), &volExt, sizeof(volExt), &requiredSize, NULL))
    {
    dwDiskNumber = volExt.Extents->DiskNumber;
    LARGE_INTEGER liLength = volExt.Extents->ExtentLength;
    }
    ::CloseHandle( hDrive );

    return dwDiskNumber;
    }


    부산멤버십 18기 선배가...

  2. skensita 2012.11.15 14:42 신고  댓글주소  수정/삭제  댓글쓰기

    EFI 환경에서는 MBR이 아닌 GPT를 쓰게 되는데요.
    이쪽도 한번 보시면 도움이 많이 될 것 같네요.