sshd_config 에 

Usedns 옵션을 no로 한다. 주석풀고.



수세 :  /etc/init.d/sshd restart

레드헷 : service sshd restart

freebsd : /etc/rc.d/ssh restart 

AND

CreateFile는 APP에서 사용하는 함수이다. 
이미 심볼릭 링크로 등록된 드라이버의 핸들을 생성하여 , app에서 조작이 가능하도록 해준다. 


CreateFile
 함수는다음 개체들을 생성하거나 열고, 그 개체에 접근하는데 사용될 수 있는 핸들을 리턴한다;

  • files
  • pipes
  • mailslots
  • communications resources
  • disk devices (Windows NT only)
  • consoles
  • directories (open only)

HANDLE CreateFile(

 LPCTSTR lpFileName// 파일의 이름에 대한 포인터

 DWORD dwDesiredAccess// 접근(read-write) 모드

 DWORD dwShareMode, // 공유 모드

 LPSECURITY_ATTRIBUTES lpSecurityAttributes// 보안 속성에 대한포인터

 DWORD dwCreationDisposition// 생성하는 방식

 DWORD dwFlagsAndAttributes// 파일 속성

 HANDLE hTemplateFile // 복사하기 위한 속성을 가진 파일의 핸들

);

Parameters

lpFileName
생성하거나 열기 위한 개체(file, pipe, mailslot, communications resource, disk device, console, or directory)의 이름을 지정하는 NULL 종료 문자열에 대한 포인터

만약 lpFileName이 경로라면, 기본적인 문자열 크기는 MAX_PATH로 제한된다. 이 한계는 CreateFile 함수가 경로를 분해하는 방식과 관련이 있다.

Windows NT: CreateFile 의 확장(W) 버전을 호출하거나 경로에 "\\?\"를 달아서(? prepending) MAX_PATH개보다 많은 문자를 경로로 사용할 수 있다. "\\?\"는 함수에 경로 분해(parsing)를 하지 말라고 통보한다. 이것은 32,000 개 정도의 유니코드 문자를 경로로 사용할 수 있게 해 준다. 그러나 경로의 각 컴포넌트들은 MAX_PATH 문자보다 많을 수 없다. 이 기법을 사용하기 위해서는 경로를 완전히 작성해야만 한다. 이것은 UNC 이름과 함께 작동하기도 한다. "\\?\"는 경로의 일부로서 무시된다. 예를 들어서 "\\?\C:\myworld\private"는 "C:\myworld\private"와 같이 처리되며, "\\?\UNC\tom_1\hotstuff\coolapps"는 "\\tom_1\hotstuff\coolapps"로 처리된다.

dwDesiredAccess
개체에 대한 접근 유형을 지정한다. 응용프로그램은 읽기 접근, 쓰기 접근, 읽기-쓰기 접근, 또는 장치 질의 접근(device query access)을 획득할 수 있다. 이 인자들은 다음값들의 조합일 수 있다.
ValueMeaning
0 개체에 대한 장치 질의 접근을 지정한다. 응용프로그램은 장치에 접근하지 않고도 장치에 속성을 질의할 수 있다.
GENERIC_READ 개체에 읽기 접근을 지정한다. 파일로부터 읽어들일 수 있으며, 파일 포인터는 이동될 수 있다. GENERIC_WRITE와 읽기-쓰기 접근을 위해 혼용된다.
GENERIC_WRITE 개체에 대한 쓰기 접근을 지정한다. 파일로부터 읽어들일 수 있으며, 파일 포인터는 이동될 수 있다. GENERIC_READ와 읽기-쓰기 접근을 위해 혼용된다.

dwShareMode
개체가 공유될 수 있는 방식을 지정하는 비트 플래그를 설정한다. 만약 dwShareMode가 0이면, 이 개체는 공유될 수 없다. 핸들이 닫힐 때까지 그 개체에 대한 연속되는 열기 연산은 실패할 것이다.

개체를 공유하기 위해서는 다음 값들 중의 하나 이상에 대한 조합을 사용해야 한다:

ValueMeaning
FILE_SHARE_DELETE Windows NT: 삭제 접근이 요청되었을 때만 개체에 대한 연속되는 열기 연산이 성공할 것이다
FILE_SHARE_READ 읽기 접근이 요청되었을 때만 개체에 대한 연속되는 열기 연산이 성공할 것이다
FILE_SHARE_WRITE 쓰기 접근이 요청되었을 때만 개체에 대한 연속되는 열기 연산이 성공할 것이다

lpSecurityAttributes
자식 프로세스에 의해서 상속될 수 있는 반환 핸들이 무엇인지를 결정하는 SECURITY_ATTRIBUTES 구조체에 대한 포인터. 만약 lpSecurityAttributes가 NULL 이면, 그 핸들은 상속될 수 없다.

Windows NT: 이 구조체의 lpSecurityDescriptor 멤버는 개체에 대한 보안 기술자(security descriptor)를 지정한다. 만약 lpSecurityAttributes가 NULL 이면 개체는 기본 보안 기술자를 얻는다. 대상 파일 시스템이 반드시 파일과 디렉토리에 대한 보안을 지원해야지만, 이 인자는 파일에서 효력을 가질 수 있다.

dwCreationDisposition
파일이 존재할 때와 존재하지 않을 때 어떻게 해야할지를 지정한다. 이 인자에 대한 더 많은 정보를 원한다면, Remarks 섹션을 참조하라. 이 인자는 반드시 다음 값들 중의 하나여야만 한다:
ValueMeaning
CREATE_NEW새로운 파일을 생성한다. 지정된 파일이 이미 존재하면 이 함수는 실패한다.
CREATE_ALWAYS새로운 파일을 생성한다. 만약 그 파일이 존재하면, 함수는 파일을 덮어쓰고, 현존하는 속성을 초기화한다.
OPEN_EXISTING파일을 연다. 파일이 존재하지 않으면 함수는 실패한다.
콘솔(console)을 포함한 장치에 대해 CreateFile 함수를 사용하고 있을 때, OPEN_EXISTING 플래그를 사용해야만 하는 이유에 대한 논의를 위해서는 Remarks 섹션을 참조하라.
OPEN_ALWAYS 만약 존재한다면 파일을 연다. 만약 파일이 존재하지 않으면, 함수는 마치 dwCreationDisposition이 CREATE_NEW였던 것처럼 새로운 파일을 생성한다.
TRUNCATE_EXISTING 파일을 연다. 한번 열리면 그 파일은 끊어지고(truncated) 그것의 크기는 0 바이트가 된다. 그 호출 프로세스는 적어도 GENERIC_WRITE 접근과 함께 파일을 열어야만 한다. 함수는 파일이 존재하지 않을 때 실패한다.

dwFlagsAndAttributes
파일에 대한 파일 속성과 플래그를 지정한다.

FILE_ATTRIBUTE_NORMAL을 오버라이드하는 모든 파일을 제외하고는, 다음 속성중의 하나의 조합이 dwFlagsAndAttributes 인자를 위해 접근 가능하다(원문 : Any combination of the following attributes is acceptable for the dwFlagsAndAttributes parameter, except all other file attributes override FILE_ATTRIBUTE_NORMAL. )

AttributeMeaning
FILE_ATTRIBUTE_ARCHIVE 파일은 압축(archive)되어야만 한다. 응용프로그램은 이 속성을 사용하여 백업이나 제거를 위해 파일에 표기(mark)한다.
FILE_ATTRIBUTE_HIDDEN 파일은 숨겨져야 한다. 순차적인 디렉토리 열거(ordinary directory listing)에 포함되지 않는다.
FILE_ATTRIBUTE_NORMAL 파일은 다른 속성 집합을 가지지 않는다. 이 속성은 혼자서 사용될(used alone) 때만 유효하다.
FILE_ATTRIBUTE_OFFLINE 파일의 데이터를 즉시 이용할 수가 없다. 오프라인 저장소에 물리적으로 이동된 파일 데이터를 지정한다.
FILE_ATTRIBUTE_READONLY 파일은 읽기 전용이다. 응용프로그램은 그 파일을 읽을 수 있으나, 읽거나 삭제할 수 없다.
FILE_ATTRIBUTE_SYSTEM 파일은 운영체제의 일부이거나, 배타적으로 사용된다.
FILE_ATTRIBUTE_TEMPORARY 임시 저장을 위해 사용되고 있는 파일이다. 파일 시스템은 데이터를 대량 저장소로 한 번에 보내는 것보다 더 빠른 접근을 위해 메모리의 데이터 모두를 유지하려고 시도한다.(원문 ; File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage.) 임시 파일은 더 이상 필요가 없어지면 응용프로그램에 의해 제거되어야만 한다.

다음 플래그들의 어떠한 조합이라도 dwFlagsAndAttributes 인자에 대해 이용 가능하다.

FlagMeaning
FILE_FLAG_WRITE_THROUGH
즉각적인 캐쉬를 통해서 쓰거나 직접 디스크로 갈 것을 시스템에 명령한다. 시스템은 여전히 쓰기 연산을 캐싱(역자주 : 빠른 연산을 위해 저장하는 기법 중 하나, cache)할 수 있지만, 그것들을 느리게 플러쉬(역자주 : 한꺼번에 이동시키는 것, flush)할 수는 없다.

원문 : Instructs the system to write through any intermediate cache and go directly to disk. The system can still cache write operations, but cannot lazily flush them.

FILE_FLAG_OVERLAPPED
시스템에 개체를 초기화할 것을 명령한다. 그래서 처리를 위해서 의미있는 시간을 취하는 연산은 ERROR_IO_PENING을 반환한다. 연산이 끝나면, 지정된 이벤트는 신호화된 상태(signaled state)로 설정된다.

원문 : Instructs the system to initialize the object, so that operations that take a significant amount of time to process return ERROR_IO_PENDING. When the operation is finished, the specified event is set to the signaled state.

FILE_FLAG_OVERLAPPE 를 지정했다면, 함수를 읽고 쓰는 파일은 반드시 OVERLAPPE 구조체를 지정해야만 한다. 즉, FILE_FLAG_OVERLAPPED가 지정되면, 응용프로그램은 중복된 읽기와 쓰기를 수행해야만 한다.

원문 : When you specify FILE_FLAG_OVERLAPPED, the file read and write functionsmust specify an OVERLAPPED structure. That is, when FILE_FLAG_OVERLAPPED is specified, an application must perform overlapped reading and writing.

FILE_FLAG_OVERLAPPED 가 지정되면, 시스템은 파일 포인터를 유지하지 않는다. 파일 위치는 반드시 lpOverlapped 인자의 일부로서 함수를 읽거나 쓰는 파일에 넘겨져야 한다.
이 플래그는 핸들에 유사하게 수행되는 하나 이상의 연산을 가능하게 한다(예를 들어, 유사한 읽기와 쓰기 연산)

원문 : This flag also enables more than one operation to be performed simultaneously with the handle (a simultaneous read and write operation, for example).

FILE_FLAG_NO_BUFFERING
명령어는 시스템에 즉각적인 버퍼링이나 캐싱을 수행하지 않고서 파일을 열것을 명령한다. FILE_FLAG_OVERLAPPED와 조합되면, 이 플래그는 최대한의 비동기 수행을 제공한다. 왜냐하면 I/O는 메모리 관리자가 동기화 연산에 의지하지 않기 때문이다. 그러나 어떠한 I/O 연산은 더 오래 걸릴 수 있다. 왜냐하면 데이터가 캐쉬에 저장되지 않기 때문이다.

FILE_FLAG_NO_BUFFERING으로 열린 파일로 작업하기 위해서 응용프로그램은 반드시 특정 요구를 만나야 한다.

  • 파일 접근은 반드시 볼륨(역자주 : 디스크 볼륨을 의미하는듯, volumes)의 섹터 크기의 정수형 배수인 파일 안의 바이트 오프셋에서 시작해야만 한다.(원문 : File access must begin at byte offsets within the file that are integer multiples of the volume's sector size.)
  • 파일 접근은 볼륨의 섹터 크기의 정수형 배수인 바이트 수를 지향해야 한다. 예를 들어 섹터의 크기가 512바이트라면, 응용프로그램은 512나 1024, 2048바이트를 읽거나 쓰겠다고 요청할 수 있다. 그러나 335나 981이나 7171바이트는 안 된다.
  • 읽기나 쓰기 연산을 위한 버퍼 주소는 섹터에 정렬되어야 한다(메모리에서 볼륨의 섹터 크기의 정수형 배수인 주소들의 정렬)(원문 : Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size)).

볼륨의 섹터 크기의 정수형 배수로 버퍼를 정렬하는 한 가지 방법은 버퍼를 할당하기 위해서 VirtualAlloc를 사용하는 것이다. 그것은 운영체제의 메모리 페이지 크기의 정수형 배수인 주소로 정렬된 메모리를 할당한다. 메모리 페이지와 볼륨 섹터의 크기는 모두 2의 승수(power) 크기이기 때문에, 이 메모리는 볼륨의 섹터 크기의 정수형 배수인 주소로 정렬될 수도 있다.

응용프로그램은 GetDiskFreeSpace 함수를 호출함으로써 볼륨의 섹터 크기를 결정할 수 있다.

FILE_FLAG_RANDOM_ACCESS
불규칙하게 접근된 파일을 지정한다. 시스템은 이 플래그를 파일 캐싱을 최적화하기 위한 계기(hint)로 사용할 수 있다.
FILE_FLAG_SEQUENTIAL_SCAN
처음부터 끝까지 순차적으로 접근된 파일을 지정한다. 시스템은 이 플래그를 파일 캐싱을 최적화하는 계기로 사용할 수 있다. 만약 응용프로그램이 파일 포인터를 임의 접근을 위해 움직인다면, 최적의 캐싱이 일어나지 않을지도 모른다; 그러나 정확한 연산은 여전히 보장된다.
이 플래그를 지정하는 것은 응용프로그램이 큰 크기의 파일을 순차 접근을 사용해서 읽어들일때 수행성을 증가시킬 수 있다. 수행성 획득은 대부분 순차적인 큰 파일을 읽어들이는 응용프로그램에 대해서 더욱 중요하다. 그러나 가끔 작은 크기의 바이트를 건너 뛰는 경우가 있다.
FILE_FLAG_DELETE_ON_CLOSE

자신에 대한 모든 핸들이 닫힌 이후에 즉시 파일을 제거하라고 운영체제에 명령한다. FILE_FLAG_DELETE_ON_CLOSE라고 지정한 파일 핸들을 제거하라는 것은 아니다.

그 파일에 대한 연속되는 열기 요청은 FILE_SHARE_DELETE가 사용되지 않으면 실패할 것이다.

원문 : Indicates that the operating system is to delete the file immediately after all of its handles have been closed, not just the handle for which you specified FILE_FLAG_DELETE_ON_CLOSE.

Subsequent open requests for the file will fail, unless FILE_SHARE_DELETE is used.

FILE_FLAG_BACKUP_SEMANTICS
Windows NT: 파일이 백업이나 재저장 연산을 위해 열리거나 생성되어야 한다고 명령한다. 운영체제는 호출 프로세스가 필요한 권한을 가지는 파일 보안 체크를 재정의하게 한다. 적절한 권한은 SE_BACKUP_NAME과 SE_RESTORE_NAME이다.

이 플래그를 설정해서 디렉토리의 핸들을 획득할 수도 있다. 디렉토리 핸들은 파일 핸들을 대신해 특정 Win32 함수에 넘겨질 수 있다.

원문 : Indicates that the file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file security checks, provided it has the necessary privileges. The relevant privileges are SE_BACKUP_NAME and SE_RESTORE_NAME.

You can also set this flag to obtain a handle to a directory. A directory handle can be passed to some Win32 functions in place of a file handle.

FILE_FLAG_POSIX_SEMANTICS
파일이 POSIX 규칙을 적용해 접근될 수 있도록 명령한다. This includes allowing multiple files with names, differing only in case, for file systems that support such naming. 이 옵션을 사용할 때는 주의를 기울여야 하는데, 이 플래그로 생성된 파일은 MS-DOS나 16비트 윈도우에서 작성된 응용프로그램을 통해서는 접근하지 못할 수도 있기 때문이다.
FILE_FLAG_OPEN_REPARSE_POINT

이 플래그를 지정하면 NTFS 분석 포인트(NTFS reparse points)의 분석 동작(reparse behavior)을 방해한다. 파일이 열릴 때, 분석 포인트를 제어하는 필터가 선택적이든 필수적이든간에  파일 핸들이 반환된다. 이 플래그는 CREATE_ALWAYS 플래그와 함께 사용될 수 없다.

원문 : Specifying this flag inhibits the reparse behavior of NTFS reparse points. When the file is opened, a file handle is returned, whether the filter that controls the reparse point is operational or not. This flag cannot be used with the CREATE_ALWAYS flag.

FILE_FLAG_OPEN_NO_RECALL
파일 데이터가 요청되지만, 원격 저장소에 계속 저장되어야만 함을 지시한다. 로컬 저장소로 다시 이동될 수는 없다. 이 플래그는 원격 저장소 시스템(remote sotrage system)이나 계층 저장 관리 시스템(Hierarchical Storage Management system)에 의해 사용된다.

만약 CreateFile이 클라이언트 측의 named pipe를 열면, dwFlagsAndAttributes 인자는 Security Quality of Service 정보를 포함할 수도 있다. 더 많은 정보를 원한다면 Impersonation Levels를 참조하라. SECURITY_SQOS_PRESENT 플래그를 지정하는 응용프로그램을 호출할 때, dwFlagsAndAttributes 인자는 다음 값 중 하나 이상을 포함할 수 있다:

ValueMeaning
SECURITY_ANONYMOUS 클라이언트를 Anonymous(익명) impoersonation level로 흉내내라고 지정한다.

원문 : Specifies to impersonate the client at the Anonymous impersonation level.

SECURITY_IDENTIFICATION 클라이언트를 Identification(증명) impersonation level로 흉내내라고 지정한다.

원문 : Specifies to impersonate the client at the Identification impersonation level.

SECURITY_IMPERSONATION 클라이언트를 Impersonation(대역) impersonation level로 흉내내라고 지정한다.

원문 : Specifies to impersonate the client at the Impersonation impersonation level.

SECURITY_DELEGATION 클라이언트를 Delegation(대표) impersonation level로 흉내내라고 지정한다.

원문 : Specifies to impersonate the client at the Delegation impersonation level.

SECURITY_CONTEXT_TRACKING 보안 추적 모드(Security Tracking Mode)가 동적(dynamic)임을 지정한다. 만약 이 플래그가 지정되어 있지 않으면, 보안 추적 모드는 정적이다.
SECURITY_EFFECTIVE_ONLY 클라이언트 보안 문맥(context)의 가능한 양상(aspect)만을 서버에 지정한다. 만약 이 플래그를 지정하지 않으면, 모든 클라이언트 보안 문맥의 양상이 이용가능해진다.

이 플래그는 서버가 클라이언트를 흉내내고 있는 동안 사용할 수 있는 그룹과 권한을 클라이언트가 제한할 수 있도록 허용한다.

원문 : Specifies that only the enabled aspects of the client's security context are available to the server. If you do not specify this flag, all aspects of the client's security context are available.

This flag allows the client to limit the groups and privileges that a server can use while impersonating the client.


hTemplateFile
템플릿 파일에 대해 GENERIC_READ 접근을 가지는 핸들을 지정한다. 템플릿 파일은 생성되고 잇는 파일에 대한 파일 속성과 확장 속성을 제공한다.

Windows 95: hTemplateFile 인자는 NULL이어야만 한다. 만약 핸들을 제공하면, 호출은 실패하고 GetLastError은 ERROR_NOT_SUPPORTED를 반환한다.

Return Values

함수가 성공하면 리턴값은 파일을 지정한 열기 핸들이다. 지정된 파일이 함수 호출 이전에 존재하고, dwCreationDisposition이 CREATE_ALWATS이거나 OPEN_ALWAYS이면, GetLastError 호출은 (함수가 성공했더라도) ERROR_ALREADY_EXISTS를 리턴한다. 만약 파일이 호출 이전에 존재하지 않으면 GetLastError은 0을 리턴한다.

만약 함수가 실패하면 리턴값은 INVALID_HANDLE_VALUE이다. 확장 에러 정보를 원하면 GetLastError를 호출한다.

Remarks

CloseHandle 함수를 사용하여 Createfile에 의해 반환되는 개체 핸들을 닫는다.

위에 기록된 것처럼. dwDesiredAcdess에 대해 0을 지정하는 것은 응용프로그램이 장치에 실제적으로 접근하지 않고도 장치 속성을 질의할 수 있도록 허용한다. 예를 들어서 응용프로그램이 플로피 디스크 장치의 크기나 그것이 지원하는 포맷을 드라이브의 플로피를 가지지 않고도 결정하고자 할 때, 이러한 유형의 질의가 유용하다.

Files

새로운 파일을 생성할 때, CreateFile 함수는 다음의 동작을 수행한다:

  • 파일 속성과 FILE_ATTRIBUTE_ARCHIVE와 함께 dwFlagsAndAttributes에 의해 지정된 플래그를 조합한다.
  • 파일 길이를 0으로 설정한다.
  • hTemplateFile 인자가 지정되면 템플릿 파일에 의해 제공되는 확장된 속성을 새로운 파일로 복사한다.

존재하는 파일을 열 때, CreateFile은 다음 동작을 수행한다:

  • 존재하는 파일 속성과 함께 dwFlagsAndAttributes에 의해 지정된 파일 플래그를 조합한다. CreateFile은 dwFlagsAndAttributes에 의해 지정된 파일 속성을 무시한다.
  • 파일 길이를 dwCreationDisposition의 값에 의거해 설정한다.
  • hTemplateFile 인자를 무시한다.
  • 만약 lpSecurityAttributes 인자가 NULL이 아니면, SECURITY_ATTRIBUTES 구조체의 lpSecurityDescriptor 멤버를 무시한다. 다른 구조체 멤버는 사용된다. 파일 핸들이 어떤 것인지 식별하기 위한 방식일 뿐인 bInheritHandle 멤버는 상속될 수 있다.

만약 플로피 디스크를 가지고 있지 않은 플로피 드라이버나, CD를 가지고 있지 않은 CD-ROM 드라이브에서 파일을 생성하려고 시도하면, 시스템은 사용자에게 디스크나 CD를 삽입하라고 요구하는 메시지 박스를 디스플레이한다. 이 메시지 박스를 디스플레이하지 않게 하기 위해서는, SetErrorMode 함수를 SEM_FAILCRITICALERRORS로 호출한다.

Windows NT: NTFS같은 정 파일 시스템에서는 개별 파일과 디렉토리를 위한 압축(compression)과 암호화(encryption)를 제공한다. 그러한 파일 시스템으로 포맷된 볼륨에서는 새로운 파일이 그 디렉토리의 압축과 암호화 속성을 상속한다.

CreateFile 함수를 사용하여 파일의 압축과 암호화 상태를 설정할 수는 없다. DeviceIoControl 함수를 사용하여 파일의 압축 상태를 설정하고, EncryptFile 함수를 사용하여 암호화 상태를 설정한다.

Pipes

CreateFile이 클라이언트의 named pipe를 열면, 함수는 listening state 안에 존재하는 named pipe의 인스턴스를 사용한다. 열기 프로세스는 요구되는 것보다 여러번 핸들을 중복할 수 있다. 그러나 한 번 열리면 named pipe 인스턴스는 다른 클라이언트에 의해 열릴 수 없다. pipe가 열려질 때 지정된 접근은 반드시 CreateNamedPipe 함수의 dwOpenMode 인자에 지정된 접근과 호환되어야만 한다. pipe에 대한 더 많은 정보를 원한다면 Pipes를 참조하라.

Mailslots

CreateFile이 클라이언트의 mailslot을 열면, 함수는 CreateMailSlot 함수로 mailslot 서버가 생성되기 이전에 mailslot 클라이언트가 로컬 mailslot을 열려고 시도하면  INVALLID_HANDLE_VALUE를 리턴한다. mailslot에 대한 더 많은 정보를 원한다면 Mailslots를 참조하라.

Communications Resources

CreateFile함수는 시리얼 포트 COM1과 같은 communications resource에 대한 핸들을 생성할 수 있다. coummunications resources에 대해 dwCreationDisposition 인자는 반드시 OPEN_EXISTING이어야만 하며, hTemplate 인자는 반드시 NULL이어야만 한다. 읽기, 쓰기, 또는 읽기-쓰기 접근이 저장될 수 있고, 핸들은 중복된 I/O를 위해 열릴 수 있다. communications에 대한 더 많은 정보를 원한다면 Communications를 참조하라.

Disk Devices

Windows NT: CreateFile함수를 사용해서 디스크 드라이버나 디스크 드라이브의 파티션을 열 수 있다. 이 함수는 디스크 장치의 핸들을 리턴한다; 그 핸들은 DeviceIOControl 함수에 의해 사용될 수 있다. 그렇나 호출이 성공하기 위해서는 다음과 같은 요구를 만족해야 한다.

  • 호출자는 하드 디스크 드라이버에 대한 연산을 성공하기 위해 운영자 권한을 가지고 있어야만 한다.
  • lpFileName 문자열은 \\.\PHYSICALDRIVEx 형식이어야만, 하드 디스크 x를 열 수 있다. 하드 디스크 번호는 0에서 시작한다. 예를 들어:
StringMeaning
\\.\PHYSICALDRIVE2 사용자 컴퓨터의 세번째 물리적 드라이브의 핸들을 획득한다.

  • lpFileName 문자열은 \\.\x 여야만 한다. 플로피 드라이브 x 를 열기위해서나 하드디스크의 파티션 x를 열기 위해서이다. 예를 들어 :
StringMeaning
\\.\A: 사용자 컴퓨터의 드라이브 A의 핸들을 획득
\\.\C: 사용자 컴퓨터의 드라이브 C의 핸들을 획득

디스크 장치가 FILE_FLAG_NO_BUFFERING 플래그로 열리지 않았다고 해도 모든 I/O 버퍼는 반드시 섹터로 정렬(메모리에서 볼륨의 섹터 크기의 정수형 배수로 주소가 정렬됨)된다는 점에 주의하라.

Windows 95: 이 기법은 논리적 드라이브를 열기 위해서는 작동하지 않는다. Windows 95에서는 지정된 형식의 문자열이 CreateFile로 하여금 에러를 발생시키도록 한다.

  • dwCreationDisposition 인자는 반드시 OPEN_EXISTING 값을 가져야 한다.
  • 플로피 디스크를 열 때나 하드 디스크의 파티션을 열 때는, 반드시 FILE_SHARE_WRITE 플래그를 dwShareMode인자에 설정해야만 한다.

Consoles

CreateFile 함수는 콘솔 입력(CONIN$)에 대한 핸들을 생성할 수 있다. 만약 프로세스가 상속이나 중복에 대한 결과로서 그것에 대한 열려진 핸들을 가진다면, 그것은 활성화된(active) 스크린 버퍼(CONOUT$)에 대한 핸들을 생성할 수도 있다. 호출 프로세스는 반드시 상속된 콘솔이나 AllocConsole 함수에 의해 할당된 것들 중 하나와 연결되어야 한다. 콘솔 핸들을 위해서 CreateFile 인자를 다음과 같이 설정한다:

ParametersValue
lpFileName CONIN$ 값을 사용해 콘솔 입력을 지정하고 CONOUT$ 값을 사용해 콘솔 출력을 지정한다
SetStdHandle 함수가 표준 입력 핸들로 재지정(redirected)되었다고 할지라도, CONIN$은 콘솔의 입력 버퍼 핸들을 얻는다. 표준 입력 핸들을 얻기 위해서는 GetStdHandle 함수를 사용한다.
SetStdHanle 함수가 표준 출력 핸들을 재재정했다고 하더라도, CONOUT$은 활성화된 스크린 버퍼에 대한 핸들을 얻는다. 표준 출력 핸들을 얻기 위해서는 GetStdHandle함수를 사용한다.
dwDesiredAccess GENERIC_READ | GENERIC_WRITE 가 is 우선권이 있지만, 어느것 하나가 접근을 제한 할 수 있다.

원문 : GENERIC_READ | GENERIC_WRITE is preferred, but either one can limit access.

dwShareMode 만약 호출 프로세스가 콘솔을 상송하거나 자식 프로세스가 콘솔에 접근할 수 있다면, 이 인자는 FILE_SHARE_READ | FILE_SHARE_WRITE여야만 한다.
lpSecurityAttributes 만약 콘솔이 상속되기 원한다면, SECURITY_ATTRIBUTES구조체의 bInheritHandle 멤버가 TRUE여야만 한다.
dwCreationDisposition CreateFile을 사용하여 콘솔을 열 때, OPEN_EXISTING을 지정해야만 한다.
dwFlagsAndAttributes 무시됨
hTemplateFile 무시됨

다음의 리스트는 fwdAccess와 lpFileName의 다양한 설정의 효과를 보여준다.

lpFileNamefwdAccessResult
CON GENERIC_READ 입력을 위해 콘솔을 연다
CON GENERIC_WRITE 출력을 위해 콘솔을 연다
CON GENERIC_READ\
GENERIC_WRITE
Windows 95: CreateFile이 실패한다; GetLastError을 ERROR_PATH_NO_FOUND를 리턴한다

Windows NT: CreateFile이 실패한다; GetLastError은 ERROR_FILE_NOT_FOUND를 리턴한다


Directories

응용프로그램은 CreateFile로 디렉토리를 생성할 수 없다; CreateDirectory나 CreateDirectoryEx를 호출해서 디렉토릴를 생성해야만 한다.

Windows NT: FILE_FLAG_BACKUP_SEMANTICS플래그를 설정함으로써 디렉토리의 핸들을 획득할 수 있다. 디렉토리 핸들은 파일 핸들 대신에 특정 Win32 함수로 넘겨질 수 있다.

NTFS와 같은 어떤 파일 시스템에서는 개별 파일과 디렉토리에 대한 압축과 암호화를 제공한다. 그러한 파일 시스템을 위해 포맷된 볼륨에서 새로운 디렉토리는 부모 디렉토리의 압축과 암호화를 상속한다.

CreateFile 함수를 사용하여 디렉토리의 압축과 암호화 상태를 설정할 수 없다. DeviceIoControl 함수를 사용하여 디렉토리의 압축 상태를 설정한다. EncryptFile 함수를 사용하여 디렉토리의 암호화 상태를 설정한다.

Windows CE: Windows CE 는 특별한 디바이스 파일 명을 사용하여 말단(peripheral) 장치에 접근한다. 이러한 이름들의 포맷에 대한 정보를 원한다면 Windows CE Device Driver Kit 문서를 참조하라.

lpSecurityAttributes 인자는 무시되며 NULL로 설정되어야만 한다.

dwFlagsAndAttributes 인자에 대해 다음 속성 플래그들은 지원되지 않는다 :

FILE_ATTRIBUTE_OFFLINE

FILE_ATTRIBUTE_TEMPORARY

dwFlagsAndAttributes인자에 대해 다음 파일 플래그들은 지원되지 않는다:

FILE_FLAG_OVERLAPPED 그러나 한번에 한 디바이스에서 다중 읽기/쓰기 펜딩(pending)은 허용된다

FILE_FLAG_SEQUENTIAL_SCAN

FILE_FLAG_NO_BUFFERING

FILE_FLAG_DELETE_ON_CLOSE

FILE_FLAG_BACKUP_SEMANTICS

FILE_FLAG_POSIX_SEMANTICS

dwFlagsAndAttributes 인자는 SECURITY_SQOS_PRESENT 플래그나 그것과 관련된 값을 지원하지 않는다

hTemplateFile 인자는 무시되며, 결과적으로 CreateFile은 새로운 파일의 확장된 속성을 복사하지 않는다

QuickInfo

  Windows NT: Requires version 3.1 or later.
  Windows: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winbase.h.
  Import Library: Use kernel32.lib.
  Unicode: Implemented as Unicode and ANSI versions on Windows NT.

 

from Devpia

출처 : MSDN 97 

'WINDDK' 카테고리의 다른 글

왕초보 디바이스 드라이버개발자를 위한 블로그  (0) 2011.10.18
AND

일단. 

구성은 
드라이버소스(C) : 컴파일하면 .sys 파일이 생성됨
APP소스(API쓰니까 CPP?) : 생성한 드라이버를 사용하는 소스. 

app에서 드라이버로 인자를 전달하면 드라이버가 받은 인자를 판단하여 Hello World를 찍어주는 과정입니다.

처음 디바이스 드라이버를 접하는 사람들한테 좋은 블로그여서 소개합니다.  

원본 : http://blog.naver.com/PostView.nhn?blogId=shshrka001&logNo=20058872164&categoryNo=3&parentCategoryNo=0&viewDate=&currentPage=2&postListTopCurrentPage=1&isAfterWrite=true&userTopListOpen=true&userTopListCount=5&userTopListManageOpen=false&userTopListCurrentPage=2

 


디바이스 드라이버 제작--도입  디바이스 드라이버1 

2008/12/20 23:14

복사http://blog.naver.com/shshrka001/20058872164

오늘부터 DDK (Device driver Development Kits) 으로 기본적인 드라이버를 빌드하는과정에 대해서 작성해보려고 합니다.

 

이유는 ,, 제가 처음 디바이스 드라이버 책을 사고,,  IOCTL메시지로 디바이스를 동작하는데, 한달이 걸렷기 때문입니다.

 

아마 누구가 옆에서 도와줫더라면 3일도 안걸렷을;;

 

그리고 이 글이 마무리 되는대로 기본적인 키보드나 마우스 필터 드라이버 제작 과정을 처음부터 올릴려고 합니다.

 

예상 되는 기한은...  저도 모릅니다. ㅋ

 

소켓 프로그래밍 내용도 작성 해야하고(이미 멀티 스레드활용 예제 까지 구현했으나 글쓰기의 귀차니즘 때문에 올리지못하는;;)

 

놀아야?? 하기도 합니다. ㅋ 연말인대 ㅋ

 

어쩻든 내일부터 하나씩 올릴예정입니다.

 

누구나 이 영역에 쉽게 접할수 있도록 그림과 함깨 올릴것입니다.

 

아마 누군가가 네이버 검색중에 이 글을 발견해서 유용하게 쓸 수 있었다면 전 만족합니다. ^^

디바이스 드라이버 빌드를 위한 준비물  디바이스 드라이버1 

2008/12/22 13:58

복사http://blog.naver.com/shshrka001/20058946306

첨부파일 (2)

모든 종류의 프로그래밍에 있어서, 일단은 Hello World 를 찍어 보는것이 시작이라고 생각합니다.

 

우리가 하려는 디바이스 드라이버를 빌드 하는것, 더 자세히 말하면 WDM드라이버를 빌드 하는것을

(이제부터는 간단하게 빌드 라고만 하겠습니다.)

을 하려면

 

ddk(Devicedriver Development Kits)와 그 안에 포함된 툴들 ::링크(http://www.microsoft.com/whdc/devtools/ddk/default.mspx) 프리웨어 입니다.

예전에는 시디에 구워서 판매 했다고 하네요..  이제는 걍 다운로드 됩니다.

 

컴파일러(vc6.0이상)  이건 다 있으실겁니다.

 

그리고 테스트를 위한

Dbgview 프로그램(완전필수) (게시글에 첨부)

드라이버 로드 프로그렘(프로그램이 있기는 하나, 이건 직접 만들어 봅시다.) (게시글에 첨부)

 

 

등이 필요하고 배움이 깊어질수록 더 많은 첨단 장비(?) 들이 필요하게 될겁니다.

 

이제 기초적인 준비물이 다 준비 되었고, ddk사용법에 대해 봅시다~!

Hello Device --빌드하기  디바이스 드라이버1 

2008/12/22 15:04

복사http://blog.naver.com/shshrka001/20058949763

첨부파일 (2)

우선 앞에의 준비물 편에서 보여드린 장비를 어텋게든 준비하셧으면.. 네 이지 빌드를 해봐야 겠지요... 아무거라도 일단 빌드가 되는것을 확인 하셔야 아마 이해가 되실겁니다.. 물론 이미 다 아시는분들고 계시지만 모르는 분들이 이 게시글을 보았다고 가정 하겠습니다.

 

우선 첨부에 있는 자료를 다운 받아서 밑에 그림에 있는것 처럼 해보시면 아마 빌드가 될것입니다. 그리고 결과물로 MSNBCVID.sys라는 드라이버를 얻으실수 있겠지요..

 


 

1.

우선 첨부를 다운 받으셔서 아무대나 간단한곳에 압축을 풉니다. 압축풀고 폴더명은 아무렇게나 하셔도 됩니다.(단 공백이 들어가면 않됩니다.) 용량이 1.56KB밖에 않되군요..

 

 

2.

압축을 푸시면 아마 파일 3개가 있으실겁니다. 이 파일들은 이름이 변경되어서는 않됩니다.

 

 

 

 

3.

 

앞서서 작성한 게시글 준비물 중에 DDK.iso라는것을 다운 받아서 설치한 후에 이용가능한 유틸입니다.

(데몬이나, 등으로 설치하세요)

 

여기서 OS 별로 다른 툴을 사용하는데요, 윈 2000미만은 않된다네요..  그리고 비스타 쓰시는분은 모르겠습니다. ㅋㅋ아마 암거나 해도 이상없겠지요?

 

 

4.

실행 하시고 나면, 아까 압축을 푸신 디렉토리의 경로명으로 디렉토리를 이동합니다.

사용방법은 대부분 알것 같지만..

 

cd 디렉토리

 

입니다.

 

그리고 절때 절때 절때 경로명으로 전달되는 문자열 중에서 공백이 있으면 않됩니다.

예를 들어서 cd C:\영화 일드\111

이럴경우 컴파일시 에러가 발생합니다.

 

 

5.

컴파일 명령어인 build를 입력 하시면 빌드가 됩니다.

 

 

 

6-1.

빌드에 성공한모습

 

 

6-2.

빌드에 실패한모습.

(~~줄)에서 ;이 빠진 문법오류 라고 하네요.

 

 

7.

못보던 폴더 2개와 txt형식의 로그파일이 하나 생성된모습

 

8.

새롭게 생긴 폴더 속에 빌드 결과물이 있습니다.

Hello Device --빌드하기2  디바이스 드라이버1 

2008/12/22 15:39

복사http://blog.naver.com/shshrka001/20058952346

첨부파일 (2)

앞에 글을 읽으셧다면 빌드를 해보셧거나 할줄 아실겁니다. 아마

 

그럼 111 폴더에 있는 파일들을 하나하나 분석해보겠습니다.~!

 

앞에 글에 있는것과 같은 파일을 하나 첨부합니다.

basic.c 는 뭐하는건지 보면 바로 답이 나오고..

 

남은

MAKEFILE와

SOURCES

는 컴파일러 에게 이것저것을 알려주는 파일입니다.

 

확장자가 없습니다.

 

메모장으로 만들고 확장자를 붙이지 않고 저장 하시면 됩니다.

 

소스파일은 c언어로만 (c++문법 제외)만들어야 한다고 일단은 생각해두시는 편이 낳을지도 모르겠습니다.

 

외부에서 호출되는 DriverEntry함수가 c++로 구성되면 c++언어 특유의 다형성 때문에 맹글링 문제가 발생하는데, 이것때문에 외부에서 DriverEntry을 찾기가 힘들어 집니다.

 

dll에서 외부로 익스포트 되는 함수를 c로 만드는 이유와 같습니다.

다형성은 c++고유의 기능이기 때문입니다.

 

 

어쨋든..

 

매모장을 이용해서 두 파일을 MAKEFILE 과 SOURCES 을 열면

 

 

 

이렇게 문자 몇게가 있습니다.

 

SOURCES 에서

 

TARGETNAME=MSNBCVID

이 값은 드라이버의 이름입니다.

출력되는 파일의 결과물의 이름이기도 합니다.

이 이름은 드라이버의 바이너리에 하드코딩 되기 때문에, 이름을 MSNBCVID.sys 에서_MSNBCVID22.sys으로 바꾼다고 해서

드라이버의 이름이 바뀌지 않습니다.

 


TARGETPATH=OBJ

컴파일된 드라이버가 나오는 위치

 

TARGETTYPE=DRIVER

컴파일 옵션인데,DRIVER 라는 값을 주면 드라이버를 컴파일 할 수 있다.

ddk로 다른 유저모드의 실행파일을 컴파일 할수도 있는데, 여기 값을 달리하면 된다.

(그 값은 모른다.;; 그냥할수 있다고 들었기 때문. ㅋ) 


SOURCES= basic.c

이것은 소스파일의 이름이다.

SOURCES 와 같은 디렉토리에 있어야 한다?(아마)

SOURCES= basic.c \basic2.c \basic3.c ...\basic.c

형식으로 다중파일을 지원한다.

 

MAKEFILE에서

!INCLUDE $(NTMAKEENV)\makefile.def

라는 문자열을 포함 해야 하는데..

뭐하는건지는 모르겠고,, 필요하다고 한다.

 

그리고 #뒤에 있는글은 주석인데..

이걸 수정할 일이 없다보니까.

어디서 구한걸 계속 돌려쓰게 되고 이글 쓰려 열어보니까 이런 주석이 달려 있네요..

 

------------------------------------------------------------------------

이제 앞번 게시물에서 다운로드 받은 파일분석을 마감 지어 보았습니다.

 

고급 기능이 많기는 하지만 일단 여기까지  (모르기 때문)

 

도움이 되었으면 합니다, ㅎ

Hello Device --드라이버 설치(동적로딩)  디바이스 드라이버1 

2008/12/22 16:25

복사http://blog.naver.com/shshrka001/20058955531

첨부파일 (2)

이번 게시물 시리즈의 중요한 목표가 이 드라이버가 Hello Device를 찍어내는것을 보는것입니다.

 

자세한 분석은 뒤에서 하고 일단 보여주기 위주로 글을 쓸 생각입니다.

 

분석까지 같이 하면, 저 입장에서는 뜬구름 잡는 이야기가 되는것 같다는 생각이 들어서입니다.

 

어쨋든,

 

드라이버를 로딩 하는 방법중 하나인 SCManager를 이용한 실행중 로딩에 대해서 써보겟습니다.

 

말이 SCManager을 사용한다는것이지..  지금은 일단 만들어진 툴을 이용해서 로딩 하겠습니다.

 

물론 나중에 SCM함수를 이용해서 로드 언로드를 해볼건데,, 그건 그때 이야기하고

 

지금은 툴을 그냥 편히 쓰렵니다.

 

받으신 파일 Dbgview와 INSTDRV를 실행 시키킨 모습니다.

(첨부는 다 준비물 편에서 첨부 해둔것들입니다. 받으셧다면 또 받을 필요 없습니다.)

 

 

Dbgview은 그냥 켜놓기만 하면 시스템 전역에서 날라오는 디버그 메시지를 알아서 잡아서 표시합니다.

 

 

INSTDRV에 방금 컴파일한 따끈따끈한 .sys파일의 완전경로를 넣고

 

install과 start를 눌러주시면,

 

설치와 디바이스의 실행이 될겁니다.

 

참고로 start를 누르는 시점에 DriverEntry 함수가 호출됩니다.

 

앞번에서 컴파일한 소스코드에는 DriverEntry 함수에

DbgPrint("드라이버 생성 성공"); 이라는 인자를 가진 

DbgPrint함수를 호출하가 때문에,

 

디버깅 뷰를 통해서 함수가 로드 되었는지를 감시할수 있습니다.

 

어쨋든 실행결과는 다음과 같습니다.

 

 

이제 다음 글에서 이렇게 생성한 드라이버의 핸들을 얻어와서, 이 드라이버를 작동시켜 보겟습니다.

Hello Device --드라이버 핸들 얻기  디바이스 드라이버1 

2008/12/22 22:10

복사http://blog.naver.com/shshrka001/20058975191

첨부파일 (1)

먼저글에 드라이버를 로딩 하는것 까지 작성 했습니다.

 

이제 로드 된 드라이버를 직접 핸들을 얻어 보겠습니다.

 

글 제일 밑에 ↑ 소스 원본있습니다. 긁으시려면 밑으로 ㅎ

 

소스코드에서 보시면 크게

1.CreateFile으로 핸들을 얻고,

2.그 핸들을 이용해서 DeviceIoControl으로 디바이스에 명령을 전달하고,

3.핸들을 닫아버립니다.

 

그리곤 종료가 됩니다.

 

명령어로 1이 전달이 되었는데,(보통은 메크로를 정의해놓고 사용합니다. 하지만 짧은 예제 이니만큼 그냥 상수를 직접 사용했습니다.)

 

이렇게 전달 되어진 명령어로 디바이스는 뭔가를 하겠지요..

 

만약 입력버퍼나 출력버퍼를 요구한다면  DeviceIoControl함수의 인자값에 버퍼의 주소를 전달하면 될거고요.

 

이렇게 전달되는 메시지의 해석은 전적으로 드라이버의 책임입니다.

 

어떠한 메시지가 전달되든 사용자모드 app나 커널은 어떤 참견도 하지 않습니다.

 

이제 전달된 메시지가 뭘 했는지 보겠습니다.

음 뭔가를 하고 디버그 메시지를 남겼네요..

 

편집한다고 몇번 출력하다보니까 아주 도배가 되어버린.. 다른 곳에서 온 메시지 들도 있네요.

 

이제 간단하게 핸들을 얻어서 앞에서 만든 드라이버를 사용해보았습니다.

 

기껏 사용한다는것이 문자열이나 출력하는것 정도입니다. ㅜㅜ

 

다음글에서는 드라이버의 소스코드를 분석해보겠습니다.

 

첨부파일은 드라이버를 위에서 소계한 코드가 컴파일된것입니다.

(앞에글에서 다운로드르 받지 않았으면 실행이 되지 않습니다.)

 

 

 

 

 

 

 

 

--------------------------

 

사진에 있는 코드

 

---------------------------

#include <stdio.h>
#include <windows.h>

void main()
{

HANDLE Divece_Handle=CreateFile(\\\\.\\MFD,
        GENERIC_READ|GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0
        );
 

 if(int(Divece_Handle) == -1)
  {
   printf("디바이스의 핸들을 얻는것에 실패 했습니다.\n");
   printf("에러코드:%d\n",GetLastError());
  }
 else
  {
   printf("디바이스의 핸들을 얻는것에 성공 했습니다.\n");
   DWORD bR;
   DeviceIoControl(Divece_Handle,//핸들
           1,//보내는 명령어
       //(원칙은 정의된 메크로를 사용하는것이다.)
          NULL,//입력 버퍼
             NULL,//그 크기
          NULL,//출력 버프
          NULL,//그 크기
           &bR,
    //메크로로 정의된 실행 결과 코드가 출력될 버퍼
            NULL //그냥 NULL
          );
   
   CloseHandle(Divece_Handle);
  }
 getchar();
}

Hello Device --드라이버 소스 분석  디바이스 드라이버1 

2008/12/22 23:04

복사http://blog.naver.com/shshrka001/20058978211

디바이스 드라이버가 뭔가요? 라고 물으면


"간단하게 말해서 사용자 모드 프로그램의 요청에 의해 커널영역에서 일을 하는 서비스"

라고 답변 하고싶습니다.

계략적인 동작방식은

1.우선 서비스가 어떤방법으로든 로딩이되고(이시점에서 DriverEntry함수 호출)

 

2.로딩이 된 드라이버를 사용자모드app가 CreateFile로 핸들을 구합니다.

 

3.ReadFile,WriteFile,DiveceIoControl,등의 함수가 보내는 명령?을 처리합니다.

 

이런식의 동작을 합니다.
4.드라이버가 언로드 될때, 제거 루틴(주로 OnUnload라고 명명)이 호출 됩니다.

 

3번에서 이런 명령들을 처리하기 위해서 커널의 IO관리자는 IRP라는 구조체를 사용합니다.

즉 사용자가 뭐라고 명령(ReadFile,WriteFile,DiveceIoControl,등등 함수사용) 하면,커널은 IRP에 명령을 담아서 드라이버로 전달합니다.

그러면 드라이버는 그 명령을 처리할수 있도록 루틴을 준비 해야 합니다.

 

이제 드라이버의 소스코드를 분석 해보겠습니다.

 

풀소스 입니다.

 

하는것도 없는소스이지만, 별로 짧지는 않네요

 

기본적인 명령어를 모두 처리는 할수 있습니다.

 

대부분이 그냥 넘겨버리기는 하지만요.

 

루틴별 분석은 2개쯤 나누어서 올리도록 하겠습니다.

 

 

----------------------------------------------------

소스 txt

 

/*
Made by KSR (shshrka001)
예제: Hello Device!!
08-12-20
*/

#include "ntddk.h"


//디바이스의 이름이 채워진 버퍼
WCHAR DeviceName[]=L"\\Device\\MMF_MyFirstDevice";
WCHAR symLinkName[]=L"\\??\\KSR081220";
PDEVICE_OBJECT g_RootkitDevice;

NTSTATUS DispatchRootion( IN PDEVICE_OBJECT theDriverObject,
       IN PIRP Irp)
{
   //관심없는 루틴 처리
   Irp->IoStatus.Status= STATUS_SUCCESS;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}

VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
{
   //언로드 루틴
   //드라이버를 제거 할때 호출
             UNICODE_STRING Name;
             /* 심볼 링크 삭제*/
             RtlInitUnicodeString( &Name, symLinkName);
    //symLinkName을 유니코드로 만든다.
             IoDeleteSymbolicLink(&Name);
             /* 디바이스 객체 삭제*/
             IoDeleteDevice(pDriverObject->DeviceObject);
             DbgPrint("드라이버 언로드");
}

 

NTSTATUS My_IOCTL(IN PDEVICE_OBJECT theDriverObject,IN PIRP Irp)
{
   //사용자 정의 명령어 처리 루틴
   PIO_STACK_LOCATION IrpStack;
   ULONG Commend_Me;
   IrpStack=IoGetCurrentIrpStackLocation(Irp);
   Commend_Me=IrpStack->Parameters.DeviceIoControl.IoControlCode;
   switch(Commend_Me)
   {
    case 1:
     DbgPrint("기본적인 예제: Hello Device!!출력");
     DbgPrint("축하합니다.");
     break;
    case 2:
     DbgPrint("받은 명령어->%d",Commend_Me);
     break;
    case 3:
     DbgPrint("받은 명령어->%d",Commend_Me);
     break;
    default:
     DbgPrint("받은 명령어->%d은 처리 불가능한 명령어 코드 
       입니다.",Commend_Me);
     break;

   }
   IoCompleteRequest( Irp, IO_NO_INCREMENT );
   return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate (IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) 
{   
   //CreateFile에 대응 되는 루틴
   //프로세스에서 핸들을 얻을때마다 호출됨
   pIrp->IoStatus.Status = STATUS_SUCCESS;
   pIrp->IoStatus.Information = 0; 
   IoCompleteRequest( pIrp, IO_NO_INCREMENT );
   return STATUS_SUCCESS;
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject,
      IN PUNICODE_STRING theRegistryPath )
{
   //시작 함수 DriverEntry 드라이버를 Start할때 호출
   int i;
   NTSTATUS status11;
   UNICODE_STRING NameString;
   UNICODE_STRING Sym_NameString;

   //사용할 이름을 전부 유니코드로 만든다.
   RtlInitUnicodeString(&NameString,DeviceName);
   RtlInitUnicodeString(&Sym_NameString,symLinkName);


   //루틴을 등록한다.
    for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
    {
      theDriverObject->MajorFunction[i]=DispatchRootion;
    }
   //관심있는 루틴을 따로 처리
   theDriverObject->DriverUnload  = OnUnload; 
   theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=My_IOCTL;
   theDriverObject->MajorFunction[IRP_MJ_CREATE] =DispatchCreate;
   //디바이스를 등록한다.
   status11=IoCreateDevice(theDriverObject,0,&NameString,
         0x00001234,0,TRUE,&g_RootkitDevice);
    if(status11==STATUS_SUCCESS)
    {
     DbgPrint("드라이버 생성 성공");

    }
    else
    {
     DbgPrint("드라이버 생성 실패");
     return STATUS_SUCCESS;
    }
   //상징적 이름을 준다.
   status11=IoCreateSymbolicLink(&Sym_NameString,&NameString);
    if (!NT_SUCCESS(status11)) 
    {
     IoDeleteDevice(g_RootkitDevice);
     DbgPrint("SymbolicLink 초기화 실폐");
     return STATUS_SUCCESS;
    }
   DbgPrint("SymbolicLink 초기화 성공");
   return STATUS_SUCCESS;
}

드라이버 로드 언로드 Class!!! (INSTDRV)모티브  디바이스 드라이버1 

2009/02/01 14:21

복사http://blog.naver.com/shshrka001/20061198826

첨부파일 (2)

드라이버 로드하는 툴로 이걸 많이 사용하던데..

 

막상 자기가 로드할라면 귀찬아지므로..

 

위의 툴에 있는 버튼이랑 같은 기능을 가지는 맴버 함수를 포함하는 class를 하나 만들었다..

 

(다른사람이 이걸 또만드는 비생산적인 일을 하지않기 위해?)

 

사용법은... 아주 간단한데..

 

public에 있는 함수들에 주석된거만 봐도 아실것같다. ㅋ(사실 주석없어도 안다.)

 

그리고 내용은 위에 INSTDRV프로그램의 버튼눌르는거랑 완전 같을거같다. 아마?

 

드라이버 파일의 경로를 전달하는 방법은 생성자를 오버로딩 한다는것에 주목하기 바란다.

성공시 ture, 실패시 false

 

!!: 드라이버의 이름하고, 드라이버 파일 이름은 다를수가 있습니다.  드라이버의 이름은 드라이버 파일 바이너리에 포함되어서 한번 빌드하면 그 뒤로는 일반적인 방법으로는 못 바꿉니다..  반면에 이름은 너무쉽게 바꿀수 있죠..

그래서 드라이버이름=파일이름에서 .sys뺀것 이라고는 생각하지 마세요..(물론 저같은 경우는 파일이름이랑 드라이버 이름이랑 같게 만들지만..)  아 그리고 파일이름이랑 드라이버 이름이랑 다르면 인자 하나 받는 생성자는 사용하실수 없습니다. 밑에 주석처리 된것처럼요..

 

활용>>

 

void main()
{
Road_Driver a("C:\\Documents and Settings\\jj\\바탕 화면\\hidusb.sys","hidusb");

//Road_Driver a("hidusb");
Sleep(1000);
a.InstallDevice();
Sleep(1000);
a.StartDriver();
Sleep(5000);
a.StopDriver();
Sleep(5000);
a.RemoveDriver();
}

'WINDDK' 카테고리의 다른 글

CreateFile함수 상세 설명  (0) 2011.10.18
AND