<?xml version="1.0" encoding="UTF-8" ?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
	<channel>
		<title>입력 제어</title>
		<link>https://autolabs.co.kr/board_cFDS08</link>
		<description></description>
		<atom:link href="https://autolabs.co.kr/board_cFDS08/rss" rel="self" type="application/rss+xml" />
		<language>ko</language>
		<pubDate>Wed, 13 May 2026 22:03:45 +0900</pubDate>
		<generator>Rhymix</generator>
			<item>
			<title>단순 프로세스 감시, 커널 감시, 후킹 기반 감시는 무엇이 다를까?</title>
			<link>https://autolabs.co.kr/board_cFDS08/1090006</link>
				<description>&lt;div editor_component=&quot;markdown&quot; style=&quot;border:#000 1px dotted; padding: 10px&quot;&gt; &lt;pre&gt; 프로세스를 감시한다고 하면 보통 &amp;ldquo;어떤 프로그램이 실행되었는지 확인하는 것&amp;rdquo; 정도로 생각하기 쉽습니다. 하지만 실제로는 감시 방식에 따라 **얻을 수 있는 정보의 깊이**, **실시간성**, **구현 난이도**가 크게 달라집니다. 이번 글에서는 다음 3가지를 구분해서 설명해보겠습니다. - 단순 감시 - 커널 감시 - 후킹 기반 감시 이 셋은 목적이 완전히 다른 기술이라기보다는, **같은 목적을 서로 다른 위치와 방식으로 수행하는 기술**이라고 보는 것이 더 정확합니다. ## 1. 먼저, 프로세스 감시란? 프로세스 감시는 말 그대로 **현재 어떤 프로그램이 실행되고 있는지**, 또는 **어떤 프로그램이 새로 실행되었고 종료되었는지 확인하는 것**입니다. 예를 들면 이런 상황입니다. - 게임 실행 여부 확인 - 런처가 본 프로그램을 실행했는지 확인 - 특정 프로그램이 종료되면 후속 동작 수행 - 실행 흐름을 분석하기 위한 기록 수집 하지만 이걸 **어떤 방식으로 감시하느냐**에 따라 성격이 달라집니다. ## 2. 세 가지 방식을 한눈에 비교 | 비교 항목 | 단순 감시 | 커널 감시 | 후킹 기반 감시 | ||||| | 핵심 개념 | 현재 상태를 주기적으로 조회 | OS 이벤트를 커널에서 직접 수신 | 특정 함수 호출을 가로채서 감시 | | 동작 위치 | 사용자 모드 | 커널 모드 | 사용자 모드 또는 커널 모드 | | 기본 방식 | Polling(반복 조회) | Event/Callback 기반 | Hook/Intercept 기반 | | 주로 보는 것 | 현재 실행 중인 프로세스 | 생성/종료 이벤트 | 함수 호출, 인자, 반환값, 내부 흐름 | | 실시간성 | 보통 | 높음 | 매우 높음 | | 놓칠 가능성 | 있음 | 낮음 | 낮음 | | 구현 난이도 | 낮음 | 높음 | 중~매우 높음 | | 시스템 위험도 | 낮음 | 높음 | 중~높음 | | 분석 깊이 | 얕음 | 중간 | 깊음 | | 적합한 용도 | 실행 여부 확인 | 생성/종료 추적 | 내부 동작 분석 | ## 3. 단순 감시란? 단순 감시는 가장 익숙하고 구현하기 쉬운 방식입니다. 쉽게 말하면: &amp;gt; &amp;ldquo;지금 이 프로그램이 떠 있나?&amp;rdquo; &amp;gt; &amp;ldquo;0.5초 뒤에 다시 확인해보자.&amp;rdquo; &amp;gt; &amp;ldquo;또 0.5초 뒤에 다시 확인해보자.&amp;rdquo; 이런 식으로 **주기적으로 프로세스 목록을 조회**하는 방식입니다. ### 예시 - `game.exe`가 실행 중인지 확인 - 특정 창 제목이 존재하는지 확인 - 런처 프로세스가 떠 있는지 검사 ### 장점 - 구현이 쉽습니다. - 드라이버가 필요 없습니다. - 시스템 위험이 낮습니다. - 자동화 스크립트 조건 분기에 활용하기 좋습니다. ### 단점 - 조회 주기 사이에 생겼다가 바로 사라진 프로세스는 놓칠 수 있습니다. - 내부 동작까지는 알기 어렵습니다. - &amp;ldquo;있다 / 없다&amp;rdquo; 확인에 가까운 수준입니다. ### 비유 단순 감시는 마치 문 앞에 1초마다 나가서 &amp;gt; &amp;ldquo;지금 누가 와 있나?&amp;rdquo; 확인하는 방식과 비슷합니다. ## 4. 커널 감시란? 커널 감시는 운영체제에 더 가까운 위치인 **커널 모드**에서 감시하는 방식입니다. 이 방식은 보통 단순 조회가 아니라, 운영체제가 다음과 같이 **이벤트를 직접 알려주는 구조**를 사용합니다. - 프로세스 생성 - 프로세스 종료 - 스레드 생성/종료 - 이미지 로드 등 즉, 감시 프로그램이 계속 확인하는 것이 아니라, 운영체제가 말 그대로 &amp;gt; &amp;ldquo;방금 프로세스가 하나 생성되었다&amp;rdquo; &amp;gt; &amp;ldquo;방금 프로세스가 종료되었다&amp;rdquo; 라고 **이벤트를 통지해주는 구조**입니다. ### 특징 - 실시간성이 좋습니다. - 짧게 실행되는 프로세스도 잡아내기 쉽습니다. - 런처 &amp;rarr; 본 프로그램 &amp;rarr; 보조 프로세스 흐름 분석에 유리합니다. - 시스템 이벤트를 더 정확하게 포착할 수 있습니다. ### 장점 - 생성/종료 순간을 놓치기 어렵습니다. - Polling보다 구조적으로 더 정확합니다. - 실행 흐름 분석에 강합니다. ### 단점 - 드라이버 개발 난이도가 높습니다. - 서명, 권한, 보안 정책 문제를 고려해야 합니다. - 잘못 구현하면 시스템 전체에 영향을 줄 수 있습니다. - 블루스크린 같은 치명적 문제로 이어질 수 있습니다. ### 비유 커널 감시는 문에 센서를 달아놓고 &amp;gt; &amp;ldquo;누가 들어오거나 나가면 바로 알려줘&amp;rdquo; 라고 하는 것과 비슷합니다. ## 5. 후킹 기반 감시란? 후킹 기반 감시는 단순히 프로세스가 실행되었는지 보는 수준을 넘어서, **프로그램 내부에서 어떤 함수가 호출되는지 직접 가로채서 확인하는 방식**입니다. 예를 들면: - `CreateProcess` 호출 감시 - `SendInput` 호출 감시 - `WriteFile` 호출 감시 - `recv`, `send` 같은 네트워크 함수 감시 - 특정 내부 함수 진입 감시 즉, 후킹은 이런 질문에 답하기 좋습니다. - 이 프로그램이 어떤 함수를 호출했는가? - 어떤 인자를 넣었는가? - 어떤 데이터를 주고받는가? - 어떤 흐름으로 내부 동작이 이어지는가? ### 장점 - 가장 깊은 수준의 분석이 가능합니다. - 함수 인자, 반환값, 호출 순서까지 볼 수 있습니다. - 경우에 따라 단순 감시나 커널 감시보다 훨씬 많은 정보를 얻을 수 있습니다. ### 단점 - 구현 난이도가 매우 높을 수 있습니다. - 대상 프로그램 버전이 바뀌면 쉽게 깨질 수 있습니다. - 충돌, 크래시, 보안 솔루션 탐지 가능성이 있습니다. - 유지보수가 어렵습니다. ### 비유 후킹 기반 감시는 문이 열렸는지만 보는 것이 아니라, &amp;gt; &amp;ldquo;누가 어떤 열쇠로 문을 열었는지, &amp;gt; 손잡이를 어느 방향으로 돌렸는지, &amp;gt; 들어오기 전에 어떤 행동을 했는지&amp;rdquo; 까지 보는 것에 가깝습니다. ## 6. 셋의 차이를 감시 깊이로 보면 감시 깊이만 놓고 보면 보통 다음과 같이 볼 수 있습니다. ```text 단순 감시 &amp;lt; 커널 감시 &amp;lt; 후킹 기반 감시 ```` 하지만 이것이 무조건 상위/하위 관계라는 뜻은 아닙니다. 정확히는 **용도가 다르다**고 보는 것이 맞습니다. * 단순 감시: 존재 여부 확인 * 커널 감시: 생성/종료 이벤트 추적 * 후킹 기반 감시: 내부 함수 수준 행위 추적 ## 7. 어떤 상황에서 무엇을 쓰면 될까? ### 1) 프로그램이 실행됐는지만 알면 된다 이 경우는 **단순 감시**면 충분합니다. 예: * `game.exe` 실행 여부 확인 * 런처가 떠 있는지 확인 * 자동화 시작 조건 체크 ### 2) 생성/종료 순간을 정확히 잡고 싶다 이 경우는 **커널 감시**가 더 적합합니다. 예: * 잠깐 실행되는 보조 프로세스 추적 * 런처가 어떤 프로세스를 생성하는지 확인 * 실행 흐름 기록 ### 3) 프로그램 내부 동작을 분석하고 싶다 이 경우는 **후킹 기반 감시**가 필요할 수 있습니다. 예: * 어떤 API가 호출되는지 확인 * 내부 함수 인자 확인 * 입력, 파일, 네트워크 처리 흐름 분석 ## 8. 실행기 분석 관점에서 보면? 자동화나 실행기 분석 관점에서는 다음처럼 생각할 수 있습니다. ### 단순 감시 * 실행기(`launcher.exe`)가 켜졌는지 확인 * 대상 게임(`game.exe`)이 떠 있는지 확인 ### 커널 감시 * 실행기가 어떤 프로세스를 실제로 생성하는지 추적 * 중간 보조 프로세스가 잠깐 떴다가 사라지는지 감시 * 생성/종료 시점을 정확히 기록 ### 후킹 기반 감시 * 실행기가 내부적으로 어떤 API를 호출하는지 분석 * 어떤 방식으로 대상 프로세스를 실행하는지 확인 * 인자 전달, 파일 접근, 입력 처리 등을 더 깊게 추적 즉, 실행 흐름의 **겉모습만 보려면 단순 감시**, **생성/종료 구조를 보려면 커널 감시**, **내부 동작까지 파고들려면 후킹 기반 감시**가 유리합니다. ## 9. 초보자 기준으로 추천하면? 처음 공부하시는 분이라면 보통 다음 순서가 좋습니다. ### 1단계: 단순 감시 먼저 프로세스 목록 조회, PID 확인, 창 찾기 같은 기초부터 익힙니다. ### 2단계: 커널 감시 그 다음, 생성/종료 이벤트가 어떻게 잡히는지 이해합니다. ### 3단계: 후킹 기반 감시 마지막으로 함수 호출을 가로채는 방식이 어떤 의미인지 공부합니다. 이 순서가 좋은 이유는, 후킹 기반 감시는 앞의 두 단계를 이해하지 못하면 개념이 너무 쉽게 섞이기 때문입니다. ## 10. 최종 정리 세 가지를 한 줄로 요약하면 다음과 같습니다. ### 단순 감시 &amp;gt; 지금 실행 중인지 반복 조회하는 방식 ### 커널 감시 &amp;gt; 프로세스 생성/종료 이벤트를 운영체제가 직접 알려주는 방식 ### 후킹 기반 감시 &amp;gt; 특정 함수 호출 자체를 가로채서 내부 동작까지 보는 방식 즉, * **단순 감시**는 쉽고 안전하지만 얕고, * **커널 감시**는 더 정확하지만 난이도가 높고, * **후킹 기반 감시**는 가장 깊지만 가장 까다롭습니다. 상황에 따라 필요한 방식은 달라지며, 무조건 한 방식이 더 우월하다고 보기보다는 **무엇을 알고 싶은지에 따라 적절한 감시 방식을 선택하는 것**이 중요합니다. ## 11. 마무리 프로세스 감시는 단순히 &amp;ldquo;실행 중이냐 아니냐&amp;rdquo;만 보는 기술이 아닙니다. 어떤 방식으로 감시하느냐에 따라, 얻는 정보의 수준이 완전히 달라집니다. * 현재 상태를 확인하고 싶은가? * 생성/종료 타이밍을 정확히 잡고 싶은가? * 내부 함수 호출 흐름까지 보고 싶은가? 이 질문에 대한 답이 곧 **단순 감시 / 커널 감시 / 후킹 기반 감시** 중 무엇을 선택할지 결정해줍니다. &lt;/pre&gt; &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1090006</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1090006#comment</comments>			<pubDate>Sat, 18 Apr 2026 07:20:46 +0900</pubDate>
		</item><item>
			<title>로직 애널라이저(Logic Analyzer)</title>
			<link>https://autolabs.co.kr/board_cFDS08/1089993</link>
				<description>&lt;p&gt;아래는 Algorithm님이 채팅창에서 말씀하신 단어들 중&amp;nbsp;&lt;strong&gt;로직라이저&lt;/strong&gt;가 뭔지 궁금해서 ChatGPT를 이용해서 발췌한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div editor_component=&quot;markdown&quot; style=&quot;border:#000 1px dotted; padding: 10px&quot;&gt; &lt;pre&gt; # 로직 애널라이저(Logic Analyzer)란 무엇인가? 전자기기나 임베디드 장비를 분석하다 보면 `UART`, `SPI`, `I2C`, `GPIO` 같은 **디지털 신호**가 제대로 오가는지 확인해야 할 때가 있습니다. 이럴 때 사용하는 대표적인 장비가 바로 **로직 애널라이저(Logic Analyzer)** 입니다. 로직 애널라이저는 디지털 회로에서 여러 신호를 동시에 캡처하고, 시간 흐름에 따라 어떤 값이 오갔는지 보여주는 계측 장비입니다. 또한 여러 디지털 신호 간의 **타이밍 관계**를 확인하고, 경우에 따라 **통신 프로토콜 디코딩**까지 수행할 수 있습니다. ## 쉽게 말하면 오실로스코프가 전압 파형 자체를 자세히 보는 도구라면, 로직 애널라이저는 **&amp;ldquo;디지털 신호가 0과 1로 어떻게 오갔는지&amp;rdquo;**, 그리고 **&amp;ldquo;각 신호가 어떤 순서와 타이밍으로 동작했는지&amp;rdquo;**를 보기 좋은 도구입니다. 특히 `I2C`, `SPI`, `UART(Serial)` 같은 디지털 통신 분석에 많이 사용됩니다. [1] ## 로직 애널라이저로 할 수 있는 일 ### 1. 통신 규격 추정 어떤 장치의 핀에 연결해서 신호를 캡처하면 클럭이 있는지, 데이터 라인이 몇 개인지, 신호 패턴이 어떤지 등을 보고 대략적으로 `UART`, `SPI`, `I2C` 같은 통신 방식인지 추정할 수 있습니다. 많은 로직 애널라이저 소프트웨어는 이런 프로토콜을 자동으로 디코딩해 보여주기도 합니다. ### 2. 송수신 데이터 확인 단순히 파형만 보는 것이 아니라, 실제로 어떤 바이트 값이 오갔는지 확인할 수 있습니다. 즉, **장치가 어떤 명령을 보내고 어떤 응답을 받는지**를 분석하는 데 매우 유용합니다. ### 3. 타이밍 문제 분석 디지털 장치는 신호의 값뿐 아니라 **언제 신호가 변했는지**가 중요합니다. 로직 애널라이저는 여러 채널을 동시에 캡처해서 신호 간 순서, 지연, 타이밍 오류 등을 파악하는 데 적합합니다. ## 오실로스코프와 차이점 오실로스코프는 전압의 실제 모양, 노이즈, 상승시간 같은 **아날로그 특성**을 자세히 보는 데 강합니다. 반면 로직 애널라이저는 많은 디지털 채널을 동시에 보면서 **논리 상태, 타이밍 관계, 프로토콜 해석**에 강합니다. 그래서 디지털 통신 디버깅에서는 로직 애널라이저가 더 실용적인 경우가 많습니다. ## 암호화 여부도 알 수 있을까? 로직 애널라이저로 **신호의 존재**, **통신 방식**, **데이터가 오가는 패턴**은 볼 수 있습니다. 하지만 통신 데이터가 암호화되어 있다면, 캡처 자체는 가능해도 **내용이 평문처럼 바로 읽히지 않을 수 있습니다**. 즉, 로직 애널라이저는 **&amp;ldquo;무슨 신호가 어떻게 오갔는지&amp;rdquo;**를 파악하는 데는 매우 유용하지만, 암호화된 프로토콜의 의미를 바로 해석하는 것은 별개의 문제입니다. 다만 암호화가 되어 있어도 **프레임 구조, 반복 패턴, 길이, 타이밍** 같은 정보는 여전히 분석 가능합니다. 이는 로직 애널라이저가 디지털 신호와 프로토콜 트래픽을 기록&amp;middot;디코딩하는 도구라는 점에서 자연스럽게 따라오는 분석 포인트입니다. ## 이런 상황에서 특히 유용합니다 * 정체불명의 보드 간 통신이 무엇인지 확인하고 싶을 때 * MCU와 센서가 정상적으로 데이터를 주고받는지 보고 싶을 때 * UART/SPI/I2C 통신 오류 원인을 찾고 싶을 때 * 버튼, 클럭, 데이터 핀의 동작 순서를 확인하고 싶을 때 * 펌웨어/하드웨어 디버깅 과정에서 실제 신호 흐름을 보고 싶을 때 ## 마무리 로직 애널라이저는 한마디로, **디지털 신호를 눈으로 보이게 만들어 주는 분석 도구**입니다. 특히 어떤 장치가 내부적으로 어떤 디지털 통신을 쓰는지 추정하거나, 신호가 실제로 오가는지 확인하거나, 프로토콜을 디코딩해서 데이터 흐름을 파악하는 데 매우 강력합니다. 다만 **암호화 여부**는 신호를 캡처하는 것과 별개의 문제이므로, 캡처가 된다고 해서 내용까지 바로 해석된다고 보기는 어렵습니다. &lt;/pre&gt; &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>	<category>Logic Analyzer</category><category>로직 애널라이저</category>			<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1089993</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1089993#comment</comments>			<pubDate>Sat, 18 Apr 2026 06:57:47 +0900</pubDate>
		</item><item>
			<title>커널드라이버 함수를 통한 프로세스 감시</title>
			<link>https://autolabs.co.kr/board_cFDS08/1089980</link>
				<description>&lt;p&gt;&lt;img alt=&quot;캡처.PNG&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/980/089/001/053a5f475388d343463e565f201de934.png&quot; /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;// 프로세스 콜백 함수&lt;br /&gt; VOID OnProcessNotify(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create) {&lt;br /&gt; UNREFERENCED_PARAMETER(ParentId);&lt;br /&gt; if (!g_PsLookupProcessByProcessId || !g_PsGetProcessImageFileName) return;&lt;/p&gt; &lt;p&gt; PEPROCESS Process = NULL;&lt;br /&gt; if (NT_SUCCESS(g_PsLookupProcessByProcessId(ProcessId, &amp;amp;Process))) {&lt;br /&gt; PCHAR ImageName = g_PsGetProcessImageFileName(Process);&lt;br /&gt; if (Create) DbgPrint(&quot;[감시] %s (%d) 프로세스가 켜졌다\n&quot;, (ImageName ? ImageName : &quot;Unknown&quot;), (ULONG)(ULONG_PTR)ProcessId);&lt;br /&gt; else DbgPrint(&quot;[감시] %s (%d) 프로세스가 꺼졌다\n&quot;, (ImageName ? ImageName : &quot;Unknown&quot;), (ULONG)(ULONG_PTR)ProcessId);&lt;br /&gt; ObDereferenceObject(Process);&lt;br /&gt; }&lt;br /&gt; }&lt;/p&gt; &lt;p&gt;// 프로세스 콜백 등록&lt;br /&gt; PsSetCreateProcessNotifyRoutine(OnProcessNotify, FALSE);&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;보시다시피 실행되는 프로세스들은 모두 감시됩니다.&lt;/p&gt; &lt;p&gt;지존오토 쓰시는분들은 실행기 통해서 스크립트 불러오셔셔 쓰실텐데&lt;/p&gt; &lt;p&gt;참고하시면 될거 같습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>Algorithm</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1089980</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1089980#comment</comments>			<pubDate>Sat, 18 Apr 2026 02:16:51 +0900</pubDate>
		</item><item>
			<title>RAW HID</title>
			<link>https://autolabs.co.kr/board_cFDS08/1089907</link>
				<description>&lt;p&gt;아래는 Algorithm님이 채팅창에서 말씀하신 단어들 중 &lt;strong&gt;RAW HID&lt;/strong&gt;가 뭔지 궁금해서 ChatGPT를 이용해서 발췌한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div editor_component=&quot;markdown&quot; style=&quot;border:#000 1px dotted; padding: 10px&quot;&gt; &lt;pre&gt; # RAW HID란 무엇인가? USB 장치를 다루다 보면 `RAW HID`라는 표현을 종종 보게 됩니다. 처음 들으면 &amp;ldquo;일반 HID와 뭐가 다른 거지?&amp;rdquo; 싶을 수 있는데, 개념은 생각보다 단순합니다. ## 1. HID부터 먼저 이해하기 HID는 **Human Interface Device**의 약자입니다. 대표적으로 키보드, 마우스, 게임패드처럼 **사람의 입력을 전달하는 USB 장치 클래스**를 말합니다. 운영체제는 HID 장치에 대해 기본 드라이버를 이미 갖고 있는 경우가 많아서, 별도 드라이버 설치 없이도 장치를 인식하고 사용할 수 있습니다. ## 2. RAW HID는 무엇인가? `RAW HID`는 보통 **HID 클래스를 이용해서 개발자가 임의로 정의한 데이터 패킷을 주고받는 방식**을 말합니다. 즉, 키보드처럼 &amp;ldquo;A 키가 눌렸다&amp;rdquo;, 마우스처럼 &amp;ldquo;커서가 움직였다&amp;rdquo; 같은 **표준 의미의 입력 장치**가 아니라, 개발자가 직접 다음과 같이 데이터 의미를 정하는 방식입니다. - 1바이트: 명령 코드 - 2~3바이트: 옵션 값 - 4~64바이트: 추가 데이터 쉽게 말하면: - **일반 HID** = 의미가 정해진 입력 장치 - **RAW HID** = HID 통로를 빌려서 임의의 데이터를 주고받는 커스텀 방식 이라고 이해하면 됩니다. HID는 Report Descriptor와 Usage를 통해 데이터를 설명하며, vendor-defined 용도도 둘 수 있습니다. ## 3. 왜 RAW HID를 쓰는가? RAW HID를 사용하는 가장 큰 이유는 보통 다음과 같습니다. ### 3.1 별도 드라이버 설치 부담이 적음 운영체제가 HID 장치를 기본적으로 지원하는 경우가 많아서, 전용 커널 드라이버 없이 통신할 수 있는 환경을 만들기 쉽습니다. ### 3.2 USB Serial(CDC) 대신 사용할 수 있음 가상 COM 포트를 쓰지 않고도 장치와 프로그램 사이에서 패킷 단위로 데이터를 주고받을 수 있습니다. ### 3.3 장치 제어용 프로토콜을 직접 설계할 수 있음 장치 상태 조회, 설정값 전송, 명령 실행 요청 같은 **전용 통신 프로토콜**을 만들기에 적합합니다. ## 4. HID에서 데이터는 어떻게 오가는가? HID는 보통 다음 3가지 형태의 Report를 사용합니다. ### 4.1 Input Report 장치에서 PC로 보내는 데이터입니다. 예: 센서 상태, 버튼 상태, 측정값 전달 ### 4.2 Output Report PC에서 장치로 보내는 데이터입니다. 예: LED 켜기, 모드 전환, 명령 전달 ### 4.3 Feature Report 주로 설정값이나 구성 정보를 주고받을 때 사용합니다. HID 스펙에서는 Input / Output / Feature Report 구조를 정의하고 있으며, Input Report는 주기적으로 들어오는 데이터, Output/Feature는 호스트가 장치에 전달하거나 조회하는 용도로 사용됩니다. :contentReference[oaicite:5]{index=5} ## 5. RAW HID를 쉽게 비유하면 RAW HID는 다음처럼 생각하면 이해하기 쉽습니다. ### 일반 키보드 HID 운영체제가 이미 의미를 알고 있습니다. - `0x04` &amp;rarr; A 키 - `0x05` &amp;rarr; B 키 ### RAW HID 운영체제는 그냥 &amp;ldquo;HID 데이터가 왔다&amp;rdquo; 정도만 보고, 실제 의미는 **내 프로그램이 직접 해석**해야 합니다. 예를 들어: - `0x01` &amp;rarr; 장치 연결 확인 - `0x02` &amp;rarr; 설정 요청 - `0x10` &amp;rarr; 현재 상태 응답 이런 식으로 **내가 규칙을 정해서 쓰는 것**이 RAW HID입니다. ## 6. 장점 RAW HID의 장점은 다음과 같습니다. - HID 기본 드라이버 활용 가능 - 별도 드라이버 설치 부담이 적은 편 - 장치와 프로그램 간 전용 프로토콜 설계 가능 - 패킷 기반이라 명령/응답 구조를 만들기 좋음 ## 7. 단점 물론 단점도 있습니다. - 데이터 의미를 표준이 아니라 **직접 정의**해야 함 - PC 쪽 프로그램도 같은 규칙으로 해석해야 함 - 시리얼 포트처럼 단순 문자열 테스트가 쉬운 구조는 아닐 수 있음 - Report ID, Report 길이, 입출력 방향 등을 정확히 맞춰야 함 ## 8. 언제 쓰면 좋은가? RAW HID는 보통 이런 경우에 잘 맞습니다. - 마이크로컨트롤러와 PC 프로그램을 직접 연결할 때 - 전용 USB 제어 장치를 만들 때 - 설정값 송수신, 상태 조회, 명령 실행 같은 패킷 통신이 필요할 때 - 드라이버 설치 과정을 단순화하고 싶을 때 ## 9. 한 줄 정리 &amp;gt; **RAW HID는 USB HID 클래스를 이용해, 개발자가 직접 정의한 데이터 패킷을 주고받는 커스텀 통신 방식입니다.** 즉, **&amp;ldquo;표준 입력장치&amp;rdquo;가 아니라 &amp;ldquo;HID 통로를 활용한 전용 데이터 통신&amp;rdquo;**이라고 이해하시면 됩니다. ## 10. 같이 보면 좋은 키워드 RAW HID를 이해할 때 함께 알아두면 좋은 용어들입니다. - USB HID - Report Descriptor - Input Report - Output Report - Feature Report - Vendor-defined Usage - CDC (USB Serial) - WinUSB ## 마무리 처음에는 `RAW HID`라는 이름 때문에 어렵게 느껴질 수 있지만, 핵심은 아주 단순합니다. **&amp;ldquo;HID 규격의 통로를 이용해서, 내가 정한 형식의 데이터를 주고받는 것&amp;rdquo;** 이 개념만 잡히면, 마이크로컨트롤러와 데스크톱 프로그램 간 통신 구조를 이해할 때 훨씬 수월해집니다.&lt;/pre&gt; &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>	<category>RAW HID</category>			<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1089907</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1089907#comment</comments>			<pubDate>Fri, 17 Apr 2026 22:11:55 +0900</pubDate>
		</item><item>
			<title>하드웨어 공부를 위한 장비 구매.....</title>
			<link>https://autolabs.co.kr/board_cFDS08/1089876</link>
				<description>&lt;p&gt;&lt;img alt=&quot;image.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/876/089/001/447ecc0f2f707ee26819670fb89b002a.png&quot; /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;image.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/876/089/001/c8cb30e591d32f279d8a8da8b736430b.png&quot; /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;요즘 HID 관심이 많다보니 스푸핑쪽 제대로 각잡고 만들려고 하니 장비 구매 고민중이긴합니다.&lt;/p&gt; &lt;p&gt;아예 그냥 마우스 전문 수리점을 차리는것도?.....&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자유</category>				<dc:creator>Algorithm</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1089876</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1089876#comment</comments>			<pubDate>Fri, 17 Apr 2026 17:01:19 +0900</pubDate>
		</item><item>
			<title>피코 제로 대량 주문</title>
			<link>https://autolabs.co.kr/board_cFDS08/1088353</link>
				<description>&lt;p&gt;&lt;img alt=&quot;캡처.PNG&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/353/088/001/7bdb788403f33446522ac9dbf9c58e72.png&quot; /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;다행이도 불량 난건 택배로 보내준다고 해서 받는김에 재주문 했습니다.&lt;/p&gt; &lt;p&gt;이번에도 과연 불량이 몇개가 나올것인가&lt;/p&gt; &lt;p&gt;개당 3290원 이네요.&lt;/p&gt; &lt;p&gt;확실히 아두이노 보다는 성능이 훨씬 좋네요.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자유</category>				<dc:creator>Algorithm</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1088353</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1088353#comment</comments>			<pubDate>Tue, 17 Mar 2026 10:06:11 +0900</pubDate>
		</item><item>
			<title>피코 제로 초기불량 당첨</title>
			<link>https://autolabs.co.kr/board_cFDS08/1088293</link>
				<description>&lt;p&gt;&lt;img alt=&quot;IMG_2855.jpeg&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/293/088/001/5fe0418d0e82bc2f05db8a904cf842b9.jpeg&quot; /&gt;&lt;/p&gt; &lt;p&gt;테스트용으로 2대 구매했으나 1대 초기불량 당첨&lt;/p&gt; &lt;p&gt;아두이노 구매했었을때는 불량 하나도 없었는데&lt;/p&gt; &lt;p&gt;불량 나온건 처음이네요.&lt;/p&gt; &lt;p&gt;너무 싼거 사서 그런가.....&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자유</category>				<dc:creator>Algorithm</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1088293</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1088293#comment</comments>			<pubDate>Sun, 15 Mar 2026 14:03:43 +0900</pubDate>
		</item><item>
			<title>조이스틱-키보드 맵핑 도구 - JoyToKey</title>
			<link>https://autolabs.co.kr/board_cFDS08/1085875</link>
				<description>&lt;p&gt;https://joytokey.net&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;MainWindow.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/875/085/001/5e6cd12ba2c54d36cb8aa6aed4488dfa.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1085875</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1085875#comment</comments>			<pubDate>Fri, 26 Dec 2025 10:15:58 +0900</pubDate>
		</item><item>
			<title>게임 컨트롤러를 에뮬레이션 도구 - ViGEm</title>
			<link>https://autolabs.co.kr/board_cFDS08/1085780</link>
				<description>&lt;p&gt;&lt;img alt=&quot;vigembus-driver-logo.webp&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/780/085/001/8c0addfbe4eea7c63a1416b6febe2b7a.webp&quot; /&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ViGEm&lt;/strong&gt;&lt;br /&gt; Windows에서 가짜 게임패드를 만들어 주는 커널 드라이버 + 사용자 라이브러리 묶음&lt;br /&gt; 프로그램이 &amp;ldquo;실제 Xbox 패드가 연결된 것처럼&amp;rdquo; Windows에 입력을 주입할 수 있게 해주는 인프라&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;https://vigembusdriver.com/&lt;/p&gt; &lt;p&gt;https://github.com/nefarius/ViGEmBus&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1085780</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1085780#comment</comments>			<pubDate>Sun, 21 Dec 2025 20:28:45 +0900</pubDate>
		</item><item>
			<title>원격 HID 키보드 마우스 제어 프로젝트 (RHKM) 개발일지 #1 - 서론</title>
			<link>https://autolabs.co.kr/board_cFDS08/1071703</link>
				<description>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;안녕하세요. 오토소장입니다.&lt;/p&gt; &lt;p&gt;예전부터 고민해오던 아이디어를 최근에 한번 실험해 보면서 시행착오를 겪어보고 있는데요.&lt;/p&gt; &lt;p&gt;그중에 하나가 &amp;#39;어떻게 하면 물리적으로 분리되어 있는 2개의 PC 환경에서 HID 키보드 마우스를 제어하고 입력 시킬 수 있을까?&amp;#39;에 대한 고민이었습니다.&lt;/p&gt; &lt;p&gt;최근에 시간적 여유가 조금 생겨 이것저것 자료 조사도 좀 하고 삽질(?)을 해보면서 조금의 성과가 있어 경험 글을 나누어 보고자 글을 써보게 되었습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;프로젝트명은&amp;nbsp;&lt;strong&gt;원격 HID 키보드 마우스 제어 프로젝트 (Remote HID Keyboard and Mouse)&lt;/strong&gt; 입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;실험의 목표를 요약하자면 유선으로 연결할 수 있는 근거리의 클라이언트 기반 보안 SW가 동작하는 PC를 제어하는 것을 목표합니다.&lt;/p&gt; &lt;p&gt;제가 생각해 본 추상적인 개념 구성도는 아래와 같습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;개념 구성도.jpg&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/703/071/001/36e191f46f4ff2208c8031dae84cc7a8.jpg&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;클라이언트 보안 SW가 하드웨어 드라이버도 감지 가능 할 수도 있지만, 대부분 소프트웨어 API를 모니터링한다라고 가정하고 본 실험을 진행해보겠습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;감사합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1071703</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1071703#comment</comments>			<pubDate>Sun, 21 Jul 2024 10:37:08 +0900</pubDate>
		</item><item>
			<title>윈11용 CP2102 USB-UART 변환기 드라이버 설치 관련 자료</title>
			<link>https://autolabs.co.kr/board_cFDS08/1071113</link>
				<description>&lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width:500px;&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;img alt=&quot;스크린샷 2024-06-15 224447.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/113/071/001/734c7b5cd6844b8b868146fd385ed356.png&quot; /&gt;&lt;/td&gt; &lt;td&gt;&lt;img alt=&quot;스크린샷 2024-06-15 222911.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1041277/113/071/001/34604558dd0e9dbee315e7e5ed0b6dc8.png&quot; style=&quot;vertical-align: middle;&quot; /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;HID 키보드/마우스 제어 솔루션을 만들기 위해 조사한 자료를 정리해봅니다.&lt;/p&gt; &lt;p&gt;윈11에서는&amp;nbsp;CP2102 USB-UART 변환기 드라이버 설치에 문제가 많아 수집한 자료입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;iframe allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; src=&quot;https://www.youtube.com/embed/r_eMEXvt0v0?si=tqbGrU8A15GTxhok&quot; title=&quot;YouTube video player&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버&lt;/p&gt; &lt;p&gt;https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads&lt;/p&gt; &lt;p&gt;&lt;a data-file-srl=&quot;1071114&quot; href=&quot;/index.php?module=file&amp;amp;act=procFileDownload&amp;amp;file_srl=1071114&amp;amp;sid=4cea41b2f21374dd3c7f6a0b8cc85c5b&quot;&gt;CP210x_Universal_Windows_Driver.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1071113</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1071113#comment</comments>			<pubDate>Sat, 15 Jun 2024 22:26:42 +0900</pubDate>
		</item><item>
			<title>아이칸 SW v8.3.2 컬렉팅</title>
			<link>https://autolabs.co.kr/board_cFDS08/1068155</link>
				<description>&lt;p&gt;컬렉팅용으로 게시판에 남겨봅니다.&lt;/p&gt; &lt;p&gt;테스트는 해보질 않아서 동작은 보장못합니다.&lt;/p&gt; &lt;p&gt;윈도우11 디펜더 기준 바이러스는 검출되지 않았습니다.&lt;/p&gt; &lt;p&gt;출처 : https://kongkongkong.tistory.com/124&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#e74c3c;&quot;&gt;&lt;strong&gt;※ 주의 : 첨부 프로그램 사용에 대한 모든 책임은 회원 본인에게 있음을 고지합니다.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1068155</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1068155#comment</comments>			<pubDate>Thu, 08 Feb 2024 06:32:25 +0900</pubDate>
		</item><item>
			<title>접근 허용 없이 한/글 2022 문서 자동으로 열기</title>
			<link>https://autolabs.co.kr/board_cFDS08/1048466</link>
				<description>&lt;h1&gt;접근 허용 없이 한/글 2022 문서 자동으로 열기&lt;/h1&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이번 시간에는 한/글 자동화 문서 열기의 첫 관문인 &lt;strong&gt;접근 허용&lt;/strong&gt; 팝업 창 없이 문서 열기에 대해서 알아보도록 하겠습니다. 한/글과 보안 승인 모듈에 대해 자세히 알아보는 시간을 가지겠습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;영상&lt;/h2&gt; &lt;hr /&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;iframe allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/vgR1ygnA6qw&quot; title=&quot;YouTube video player&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;구독과 좋아요 부탁드려요^^&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;예제 파일&lt;/h2&gt; &lt;hr /&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a data-file-srl=&quot;1051753&quot; href=&quot;?module=file&amp;amp;act=procFileDownload&amp;amp;file_srl=1051753&amp;amp;sid=0c3f2e8be9bf2ff1aeed6e0f0169dd0b&amp;amp;module_srl=1040965&quot;&gt;접근허용 메세지 없이 문서열기.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;보안 승인 모듈과 접근 허용&lt;/h2&gt; &lt;hr /&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;한/글 문서는&amp;nbsp;외부 프로그램에 의해 오픈할 때 보안 승인 모듈을 통해 접근할 수 있습니다. 오토핫키 언어를 이용해서 자동으로 문서를 열때 보안 승인 모듈을 체크하지 않으면 아래 그림과 같이 &amp;quot;접근 허용&amp;quot; 창이 표시됩니다.&amp;nbsp;이로 인해 사람이 직접 클릭해줘야 하는 경우가 발생합니다. 따라서&amp;nbsp;후속으로 작업해야 하는 문서 자동화 작업을 더 이상 진행할 수 없는 문제가 발생합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;2022_09_02_22_09_26_226.gif&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/466/048/001/7871dd15a4ce4f2ea951071240613dc9.gif&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;레지스트리에 보안 승인 모듈&amp;nbsp;설정하기&lt;/h2&gt; &lt;hr /&gt; &lt;h3&gt;&amp;nbsp;&lt;/h3&gt; &lt;h3&gt;보안 승인 모듈을 로컬 폴더에 복사&lt;/h3&gt; &lt;p&gt;첨부 된 예제 파일(접근허용 메세지 없이 문서열기.zip)의 &amp;quot;FilePathCheckerModuleExample.dll&amp;quot;를 &amp;quot;C:\&amp;quot; 또는 원하는 경로에 복사합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;1.png&quot; border=&quot;1&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/466/048/001/2d2252f95d2651f50a14e8d486607b22.png&quot; style=&quot;border: 1px solid;&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;레지스트리에 파일 경로 설정&lt;/h3&gt; &lt;p&gt;레지스트리 편집기(regedit) 창에서 &amp;quot;컴퓨터\HKEY_CURRENT_USER\SOFTWARE\HNC\HwpAutomation\Modules&amp;quot; 경로에 문자열 값을 새로 추가합니다. 이름은&amp;nbsp;&lt;strong&gt;FilePathCheckerModule, &lt;/strong&gt;값 데이터는&lt;strong&gt;&amp;nbsp;c:\FilePathCheckerModuleExample.dll &lt;/strong&gt;로 수정합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;2.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/466/048/001/334d0cb97ad2f734240538dd028ad125.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;오토핫키에서 설정한 보안 승인 모듈 등록하기&lt;/h2&gt; &lt;hr /&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;한/글 2022의 Automation API 중 보안 승인 모듈을 호출 하는 함수는&amp;nbsp;&lt;strong&gt;RegisterModule()&lt;/strong&gt; 입니다. RegisterModule은 한/글 컨트롤에 부가적인 모듈을 등록하는 함수입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div code_type=&quot;Python&quot; collapse=&quot;false&quot; editor_component=&quot;code_highlighter&quot; first_line=&quot;1&quot; highlight=&quot;&quot; nogutter=&quot;false&quot; style=&quot;font-family:&#039;DejaVu Sans Mono&#039;, &#039;Courier New&#039;, Courier, monospace !important; border:#666 1px dotted;border-left:#2AE 5px solid;padding:5px;background:#FAFAFA url(&#039;./modules/editor/components/code_highlighter/component_icon.gif&#039;) no-repeat top right;&quot; title=&quot;&quot;&gt;IHwpObject.RegisterModule(&amp;quot;FilePathCheckDLL&amp;quot;,&amp;nbsp;&amp;quot;FilePathCheckerModule&amp;quot;)&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;첫 번째 인자는 모듈&amp;nbsp;유형 (ModuleType)으로 크게 FilePathCheck와 UserAction 모듈 2가지 중 하나를 등록할 수 있습니다.&amp;nbsp;FilePathCheck는&amp;nbsp;FilePathCheckProc, FilePathCheckDLL, FilePathCheckHandle로 다시 분류할 수 있습니다. 이번 포스팅에서는 DLL 형태의 보안 승인 모듈을 사용하기 때문에&amp;nbsp;&lt;strong&gt;FilePathCheckDLL&amp;nbsp;&lt;/strong&gt;를 입력합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width:95%;&quot;&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;&lt;strong&gt;모듈 유형 (ModuleType)&lt;/strong&gt;&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;&lt;strong&gt;모듈 유형 (ModuleType)&lt;/strong&gt;&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;&lt;strong&gt;모듈 데이터 (ModuleData)&lt;/strong&gt;&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;FilePathCheck&lt;/td&gt; &lt;td&gt;FilePathCheckDLL&lt;/td&gt; &lt;td&gt;파일경로 승인모듈을 DLL 형태로 추가&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FilePathCheck&lt;/td&gt; &lt;td&gt;FilePathCheckProc&lt;/td&gt; &lt;td&gt;파일경로 승인모듈을 Callback Procedure 형태로 추가&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FilePathCheck&lt;/td&gt; &lt;td&gt;FilePathCheckHandle&lt;/td&gt; &lt;td&gt;파일경로 승인모듈에 제공할 Instance Handle&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UserAction&lt;/td&gt; &lt;td&gt;UserAction&lt;/td&gt; &lt;td&gt;UserAction DLL 모듈을 추가&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;두 번째 인자는 모듈의 유형에 따른 데이터 정보(ModulData) 입니다. 첫 번째 인자에 입력한 모듈의 유형에 따라 데이터를 입력할 수 있습니다. 모듈 유형별 필요한 데이터는 아래 표와 같습니다. 첫 번째 인자를&amp;nbsp;&lt;strong&gt;FilePathCheckDLL&lt;/strong&gt;를 입력했으므로&amp;nbsp;Registry에 등록된 DLL 모듈 경로 키 값인&amp;nbsp;&lt;strong&gt;FilePathCheckerModule&lt;/strong&gt;를 입력합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width:95%;&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;strong&gt;모듈 유형 (ModuleType)&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;&lt;strong&gt;모듈 데이터 (ModuleData)&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;&lt;strong&gt;설 명&lt;/strong&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FilePathCheckDLL&lt;/td&gt; &lt;td&gt;Registry에 등록된 DLL 모듈 경로 키 값&lt;/td&gt; &lt;td&gt;Registry에 등록된 DLL 모듈 경로 키 값&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FilePathCheckProc&lt;/td&gt; &lt;td&gt;Function Pointer&lt;/td&gt; &lt;td&gt;사용자가 정의한 Callback 함수의 함수 포인터&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FilePathCheckHandle&lt;/td&gt; &lt;td&gt;Control ID&lt;/td&gt; &lt;td&gt;Control을 구분할 목적으로 사용되는 Control ID&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UserAction&lt;/td&gt; &lt;td&gt;Registry에 등록된 DLL 모듈 경로 키 값&lt;/td&gt; &lt;td&gt;Registry에 등록된 DLL 모듈 경로 키 값&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;FilePathCheckerModule() 함수를 통해 보안 승인 모듈이 정상적으로 등록되었다면 true, 비정상이면 false를 반환 합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;결과&lt;/h2&gt; &lt;hr /&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오토핫키에서 보안 승인 모듈을 정상적으로 등록하면 아래와 같이 접근 허용 창이 표시 되지 않고 문서가 열리는것을 확인할 수 있습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;2022_09_02_22_00_32_891.gif&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/466/048/001/04bc7c00b99959ae5922a955b941db81.gif&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1048466</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1048466#comment</comments>			<pubDate>Sun, 18 Sep 2022 02:21:30 +0900</pubDate>
		</item><item>
			<title>아래아한글 2022와 HWPFrame.HwpObject의 연동에 대한 이해</title>
			<link>https://autolabs.co.kr/board_cFDS08/1048688</link>
				<description>&lt;p&gt;안녕하세요. 오토소장 김효복입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;한/글 2022 문서를 자동으로 제어할 때 아래 스크립트와 같이 한/글의 오브젝트 정보를 관리하는&amp;nbsp;&lt;strong&gt;HWPFrame.HwpObject&lt;/strong&gt;라는 문자열을 이용하여 인터페이스 객체 정보를&amp;nbsp;얻는것부터 시작합니다.&amp;nbsp;그렇다면 HWPFrame.HwpObject는 한/글 2022 (hwp.exe)와 어떻게 연동되는것일까요?&lt;/p&gt; &lt;div code_type=&quot;Python&quot; collapse=&quot;false&quot; editor_component=&quot;code_highlighter&quot; first_line=&quot;1&quot; highlight=&quot;&quot; nogutter=&quot;false&quot; style=&quot;font-family:&#039;DejaVu Sans Mono&#039;, &#039;Courier New&#039;, Courier, monospace !important; border:#666 1px dotted;border-left:#2AE 5px solid;padding:5px;background:#FAFAFA url(&#039;./modules/editor/components/code_highlighter/component_icon.gif&#039;) no-repeat top right;&quot; title=&quot;&quot;&gt;IHwpObject&amp;nbsp;:=&amp;nbsp;ComObjCreate(&amp;quot;HWPFrame.HwpObject&amp;quot;)&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h1&gt;HWPFrame.HwpObject란?&lt;/h1&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오토핫키와 한/글 2022와 같은 외부 라이브러리와 연동하기 위해서는 오토핫키에서 지원하는 표준 라이브러리(API&amp;nbsp;함수)의&amp;nbsp;DllCall()이나 ComObjCreate()를 이용하여 제어를 시작합니다. 한/글 2022(hwp.exe)는&amp;nbsp;외부 클라이언트에서 문서 자동화를 위해 COM (Component Object Model) 기반의&amp;nbsp; 서버를 내장하고 있습니다. 쉽게 말해, hwp.exe 내부에 문서 자동화를 위한 API 함수들이 별도의 모듈로 내장되어 있다고 이해하시면 됩니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;HWPFrame.HwpObject는 한/글 2022에 내장되어 있는 COM 모듈의 메인 인터페이스라고 생각하시면 됩니다. 즉, 이 인터페이스를 통해서 하위의 자동화 API 함수들에 접근하여 한/글 2022를 제어할 수 있습니다. 아래 그림은 HWPFrame.HwpObject가 가지고 있는 인터페이스들을 트리구조로 표현한 것입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;IHwpObject.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/688/048/001/8096a353340ac01f82a256ab07510698.png&quot; /&gt;&lt;/p&gt; &lt;pre&gt; 쉽게 말해, 오토핫키에서 &lt;strong&gt;ComObjCreate(&amp;quot;HWPFrame.HwpObject&amp;quot;) &lt;/strong&gt;를 수행하면 반환값으로 IHwpObject를 얻을 수 있습니다. 이 IHwpObject를 통해 하위의 인터페이스들을 이용할 수 있습니다. &lt;/pre&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h1&gt;&lt;strong&gt;HWPFrame.HwpObject&lt;/strong&gt;는 어떻게 hwp.exe를 찾을 수 있나?&lt;/h1&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에서 hwp.exe는 COM기반의 모듈이라고 했습니다. 일반적인 DLL 형태의 외부 라이브러리의 경우 dll&amp;nbsp;파일의 경로를 지정하여 인터페이스를 합니다. 하지만 COM은 GUID 또는 CLSID라고 하는 고유식별자를 통해서 모듈을 찾습니다. COM 모듈은 일반적으로 윈도우 레지스트리(Registry)에 등록해서 사용합니다. 쉽게 말해 고유식별자인 GUID 또는 CLSID를 레지스트리에 등록하여 관리합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자 그럼 지금부터 HWPFrame.HwpObject를&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;ComObjCreate()로 호출해서 어떤 순서로 hwp.exe를 찾는지 단계별로 추적해봅시다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Regedit에서&amp;nbsp;&lt;strong&gt;HWPFrame.HwpObject 찾기&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;첫 단계는 오토핫키 스크립트의&amp;nbsp;ComObjCreate()에 첫 번째 인자로 입력한 &amp;quot;HWPFrame.HwpObject&amp;quot;를 레지스트리에서 찾습니다.&lt;/p&gt; &lt;p&gt;아래 그림은 레지스트리에 등록된&amp;nbsp;HWPFrame.HwpObject를 찾은 모습입니다.&amp;nbsp;HWPFrame.HwpObject를 키로 하여 고유식별자인 GUID 또는 CLSID를 찾습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;1.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/688/048/001/52093ebc674c7ee69a332b7a43430c59.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;고유식별자(GUID 또는 CLSID)로 hwp.exe 경로 찾기&lt;/h3&gt; &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; &lt;p&gt;두 번째는 위에서 찾은 고유식별자를 레지스트리에서 한번 더&amp;nbsp;&amp;nbsp;검색하여 COM 모듈의 본체가 있는 hwp.exe의 경로를 찾습니다.&lt;/p&gt; &lt;p&gt;왼쪽에 보면 LocalServer32라는 폴더가 보입니다. 이것은 COM의 구조를 말합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;COM의 형태는&amp;nbsp;크게 In-Process 모델과 out-of-process 모델 두 종류가 있습니다.&amp;nbsp;In-Process 모델은 보통 DLL 형태로 만들어지며,&amp;nbsp;out-of-process 모델은 한/글 2022 (hwp.exe) 처럼 EXE 형태로 만들어집니다. out-of-process 모델은 레지스트리에 LocalServer32 형태로 관리합니다.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;LocalServer32 폴더를 선택하면 오른쪽&amp;nbsp;데이터 부분에 hwp.exe의 경로를 확인할 수 있습니다. 또한 hwp.exe를 자동화 제어를 위해 Automation 모드로 모듈을 호출하는것을 확인할 수 있습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;2.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/1040965/688/048/001/e7ae578e313b483b6b466375673ba2af.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; &lt;h3&gt;hwp.exe 모듈과 연결&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자. 이제 COM 모듈인 hwp.exe가 어느 경로에 있는지&amp;nbsp;찾았으니 오토핫키와 IUnknown 인터페이스를 통해 연결합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h1&gt;마무리 하며&lt;/h1&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;뭔가 많이 복잡해보이죠? 정리해보자면 다음과 같습니다.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;한/글 2022 (hwp.exe)의&amp;nbsp;내부에 자동화 모듈이 탑재되어 있으며, HWPFrame.HwpObject 이름으로 인터페이스를 연결할 수 있다.&lt;/li&gt; &lt;li&gt;ComobjCreate()는&amp;nbsp;dllcall() 처럼 *.dll 파일을 찾는게 아니라 레지스트리(Registry)의 고유식별자(CLSID)를 이용하여 찾는다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;인터넷에 검색하면 HWPFrame.HwpObject를 사용한 예제가 많습니다. 하지만&amp;nbsp;HWPFrame.HwpObject가 어떤 구조로 이루어져 있고 한/글 2022(hwp.exe)와 어떤 절차로 연결되는지에 대한 내용이 잘 다루어져 있지 않아 한번 정리해보았습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h1&gt;&amp;nbsp;&lt;/h1&gt; &lt;p&gt;[참고문헌]&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.hancom.com/board/devdataView.do?board_seq=47&amp;amp;artcl_seq=4082&amp;amp;pageInfo.page=&amp;amp;search_text=&quot; target=&quot;_blank&quot;&gt;한글과컴퓨터,&lt;em&gt;한/글 오토메이션 API 가이드 (2010), p1.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1048688</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1048688#comment</comments>			<pubDate>Mon, 05 Sep 2022 19:24:53 +0900</pubDate>
		</item><item>
			<title>한컴오피스 아래한글 ActiveX Control API 개발자 매뉴얼</title>
			<link>https://autolabs.co.kr/board_cFDS08/1048150</link>
				<description>&lt;p&gt;한글과컴퓨터의 아래아한글을 자동으로 제어하기 위해 필요한&amp;nbsp;ActiveX Control API 개발자 매뉴얼 입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래아한글 자동화도 연재 한번 시작해볼게요!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.hancom.com/board/devmanualList.do?gnb0=25&amp;amp;gnb1=81&quot;&gt;https://www.hancom.com/board/devdataView.do?board_seq=47&amp;amp;artcl_seq=4082&amp;amp;pageInfo.page=&amp;amp;search_text=&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/1048150</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/1048150#comment</comments>			<pubDate>Wed, 31 Aug 2022 18:31:04 +0900</pubDate>
		</item><item>
			<title>무료용 아두이노 매크로 펌웨어를 만들어서 공개합니다.</title>
			<link>https://autolabs.co.kr/board_cFDS08/971780</link>
				<description>&lt;p&gt;안녕하세요, 벌써 두달여의 시간이 지났네요..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;아두이노 절대좌표이동문제 해결했다고, 글을 올린뒤 차일피일 미뤄오다가 드디어 무료버젼을 공개하게 되었습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;무료버젼은 따른게 아니라 1회에 사용하실수 있는 30분의 시간제한이 있습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;30분이 넘으면 자동으로 정지모드로 들어가게 되고, 다시 이용을 위해서는 아두이노의 리셋버튼을 눌러서 이용하시면 계속해서&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;사용하실수가 있습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;30분의 시간제한이 불편하신분들께서는 개발하느라 수고한 개발자에게 피자한판값 후원해 주시면 언제든지 불편함을 해결해 드리겠습니다. ^^&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;여기에 파일공개는 어려운것 같고, 제 블로그 주소를 남겨놓습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;필요하신분들께서는 참조하시면 될것 같습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://url.kr/3uyd4w&quot; target=&quot;_blank&quot;&gt;https://url.kr/3uyd4w&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>	<category>무료용</category><category>아두이노</category><category>매크로</category><category>펌웨어를</category><category>만들어서</category><category>공개합니다.</category>			<dc:creator>윈포에버</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/971780</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/971780#comment</comments>			<pubDate>Fri, 23 Jul 2021 16:00:40 +0900</pubDate>
		</item><item>
			<title>아두이노로 마우스 절대좌표이동 구현했습니다.(글밑에 동영상링크 첨부)</title>
			<link>https://autolabs.co.kr/board_cFDS08/950458</link>
				<description>&lt;div class=&quot;document_950448_950378 xe_content&quot;&gt; &lt;p&gt;안녕하세요!&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;40대 중반을 넘어서고 경남에 살고 있는 아재입니다. ^^&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;매크로 관련한 사이트가 오토랩과 테일스타 사이트가 있다는건 얼마되지 않았고,,,오토랩은 오늘 가입하게 되었습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;다름이 아니라, 제가 20-30대때는 소프웨어적으로 매크로를 직접 코딩해서 돌리고 했었는데 요즘은 소프트웨어 방식은 거의 불가능하게 되었더군요.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그래서 알아보던 중에, 지X오토, HID스틱, 일부 아두이노로 하드웨어 방식으로 매크로 돌린다는걸 알게 되었습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;지X오토, HID스틱은 가격이 만만치가 않고, 아두이노는 레오나르도 보드가 몇천원 하지 않아서 구매를 하고, 직접 코딩을 해보았습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;제가 한때 프로그래머다보니, 아두이노 레오나르도를 구매를 해서 코딩을 해서 구현을 해보니 문제가 마우스 좌표이동이 절대좌표방식으로는 불가능하더군요. 몇몇 외부라이브러리가 있긴 한데,,거의 안된다고 보면 되더군요...&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그래서 그냥 제가 직접 코딩을 하고 몇일동안 아두이노 스캐치로 직접 로직을 구현했습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;결과는 글제목처럼 성공을 했습니다. 기존의 소프트웨어직인 방식으로 마우스컨트롤 하는 속도와 대동소이하게 나오고,&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;제가 구현한 로직으로 사람과 비슷한 마우스 움직임까지 구현할수 있도록 설정옵션도 구현을 했습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그리고 마우스 절대좌표 이동시 목적지점과 좌표 오차값이 1픽셀차이이내였습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그리고, 오토핫키, 파이썬, C#, 카카오토, NGM매크로, 기타매크로등 어떤 랭귀지로도 아두이노를 컨트롤 할수 있도록 commandline 명령어 툴로 제어 가능하도록 하였습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;오토랩에 제가 글을 쓴이유는 혼자서 쓰기는 그렇고, 필요한 수요가 있다면 같이 공동구매형식이나 아두이노 레오나르도 판매업자분이 계신다면 제가 기술지원을 하고, 판매를 해보는것은 어떨지 궁금해서 매크로 전문가분들이 많이 계시는 오토랩에 글을 적게 되었습니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;아! 한가지는 아두이노스케치에 코딩되어 있는 소스는 공개하지 않을 예정입니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;긴글 읽어주셔서 감사드리고, 관심 계시는분들이나 전문가님들 쪽지나 답변부탁드립니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;아래는 시연동영상 링크 입니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://serviceapi.nmv.naver.com/flash/convertIframeTag.nhn?vid=63395AE12B0BACEFEC413A905DE32A8E5663&amp;amp;outKey=V12958975f1a04fc60dfd376ceb8a62f5cee19f5e17673de463e3376ceb8a62f5cee1&amp;amp;width=544&amp;amp;height=306&quot;&gt;https://serviceapi.nmv.naver.com/flash/convertIframeTag.nhn?vid=63395AE12B0BACEFEC413A905DE32A8E5663&amp;amp;outKey=V12958975f1a04fc60dfd376ceb8a62f5cee19f5e17673de463e3376ceb8a62f5cee1&amp;amp;width=544&amp;amp;height=306&lt;/a&gt;&lt;/p&gt; &lt;/div&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>	<category>아두이노</category><category>아두이노 매크로</category><category>아두이노 HID</category><category>절대좌표</category><category>HID</category><category>오토핫티</category><category>지존오토</category><category>NGM</category>			<dc:creator>윈포에버</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/950458</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/950458#comment</comments>			<pubDate>Sun, 09 May 2021 14:02:29 +0900</pubDate>
		</item><item>
			<title>장비 없이 하드웨어 매크로 만들기 (Class DD)</title>
			<link>https://autolabs.co.kr/board_cFDS08/832994</link>
				<description>&lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;안녕하세요. 엔지엠소프트웨어입니다. 오늘 알아볼 내용은 하드웨어 매크로를 쉽게 제작할 수 있도록 도와주는 클래스 디디입니다. 매크로 관련쪽에 조금이라도 관심있는 분들은 다들 알고 계실거라고 생각합니다. 하드웨어 방식으로 동작하는 매크로는 크게 지존오토와 엔지엠 매크로가 있습니다. 엔지엠은 10,000원 미만의 아두이노를 사용하고 있습니다. 하지만, 클래스 디디는 150원정(1위안)도 합니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/QebrN/btqCqOiHcSK/LukpQolIxka442mrRgeVOk/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:482px;&quot; width=&quot;482&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:1.6;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;위 사이트에서 모듈을 다운로드 받을 수 있습니다. 모듈은 32비트와 64비트가 구분되어 있는데요. 엔지엠의 버전에 맞게 추가하면 자동으로 인식됩니다. 우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/cWcG7w/btqCqND03GC/uwupnRMbjOWutlqJfCyhv1/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:740px;&quot; width=&quot;740&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;오른쪽 컨트롤 독 하단에서 &lt;b&gt;외부 API&lt;/b&gt;를 클릭하세요~&lt;/p&gt; &lt;ol style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;외부 모듈 카테고리 확장&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;클래스 디디 클릭&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;속성 클릭&lt;/li&gt; &lt;/ol&gt;&lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/X9cgp/btqCn05gc8P/1tUJWlaY7Hok6Qfdju31zk/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:740px;&quot; width=&quot;740&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:1.6;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;아래와 같이 클래스 디디 모듈을 선택하고, 아두이노와 동일하게 자연스러운 이동을 위한 설정값들을 입력합니다. 기본 값으로 둬도 무방합니다. 참고로, 아두이노는 인터페이스가 비트단위라서 마우스가 한번에 0~127 범위에서 이동이 가능합니다. 클래스 디디는 제약없이 자유롭게 사용할 수 있습니다.&lt;/p&gt; &lt;ol style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;클래스 디디 모듈 선택 (32비트 또는 64비트 선택)&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;마우스의 클릭과 키보드의 텍스트 쓰기 추가&lt;/li&gt; &lt;/ol&gt;&lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/Vl0So/btqCqMZqgDk/0RD8rP0N488bBk5MUJ6j10/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:740px;&quot; width=&quot;740&quot; /&gt;&lt;/p&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;font-size:14px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/div&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;font-size:14px;color:rgb(51,51,51);line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;span style=&quot;font-size:16px;&quot;&gt; &lt;/span&gt;&lt;/div&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;마우스 클릭과 키보드가 정상 동작하는지 확인하는 테스트입니다. 따라서, 메모장을 하나 띄워놓고, 마우스는 메모장을 클릭해서 활성화해야 합니다. 키보드는 현재 선택된 위치에 텍스트가 입력되기 때문입니다.&lt;/p&gt; &lt;ol style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:1.6em;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;&quot;&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;line-height:2;letter-spacing:-.02em;text-align:justify;&quot;&gt;IME Mode를 True로 변경&lt;/div&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;line-height:2;letter-spacing:-.02em;text-align:justify;&quot;&gt;&lt;b&gt;※ 한영을 자동으로 감지하여 처리해줍니다.&lt;/b&gt;&lt;/div&gt; &lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;메모장에 입력할 텍스트 &quot;안녕하세요^^&quot; 입력&lt;/li&gt; &lt;/ol&gt;&lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/bsqtL0/btqCoQOSP94/7w8CsLEzmojZn498ZBEYL1/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:740px;&quot; width=&quot;740&quot; /&gt;&lt;/p&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;font-size:14px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/div&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;font-size:14px;color:rgb(51,51,51);line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;span style=&quot;font-size:16px;&quot;&gt; &lt;/span&gt;&lt;/div&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;스크립트를 실행하면 아래와 같이 메모장이 클릭되고, 텍스트가 입력되는 것을 알 수 있습니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;img.gif&quot; src=&quot;https://k.kakaocdn.net/dn/qchl2/btqCpQnAcYw/mh1oaYoMkxwXO66Q6tcl9K/img.gif&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:740px;&quot; width=&quot;740&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:1.6;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;생각보다 간단하죠^^? 아두이노와 유사한 방식으로 사용할 수 있기 때문에 클래스 디디만 구한다면 사용하는데 크게 어려운 부분은 없을겁니다. 그리고, 가격적인 면에서도 상당히 저렴하거든요. 어려운 부분은 구매할 수 있는 방법을 잘 모른다는 것입니다. 홈페이지에 들어가서 보더라도 한자로 되어 있다보니 망설여지는 부분이죠^^;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;img.png&quot; src=&quot;https://k.kakaocdn.net/dn/chdivf/btqCtXMtsHs/AB1IB1pKoEU0TvLY4zjNZ1/img.png&quot; style=&quot;margin:0px;padding:0px;vertical-align:middle;font-size:14px;height:auto;color:rgb(51,51,51);font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.28px;background-color:rgb(255,255,255);width:203px;&quot; width=&quot;203&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt;&lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;b&gt;마우스 동작&lt;/b&gt;&lt;/p&gt; &lt;ul style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;이동 거리: 하드웨어 방식으로 마우스를 이동할 때 거리를 설정합니다. 최대 이동 거리는 127이므로 1~127 사이의 값을 사용해야 합니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;이동 속도: 0, 0 좌표에서 1270, 0 좌표로 이동한다면 127만큼 10번 이동합니다. 이 때 각각의 구간마다 딜레이를 설정합니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;이동 반복: 마우스가 이동할 때 목표 지점에 정상적으로 도착했는지 확인하는 횟수입니다.&lt;/li&gt; &lt;/ul&gt;&lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt;&lt;p align=&quot;justify&quot; style=&quot;margin:20px 0px 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt; &lt;/p&gt; &lt;p align=&quot;justify&quot; style=&quot;margin:1px auto 0px;padding:0px;font-size:16px;color:rgb(51,51,51);line-height:2;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);text-align:justify;&quot;&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul style=&quot;margin:0px auto 32px;padding:0px 0px 0px 10px;font-size:16px;color:rgb(51,51,51);line-height:1.6em;font-family:&#039;AppleSDGothicNeo-Regular&#039;, &#039;Malgun Gothic&#039;, &#039;맑은 고딕&#039;, dotum, &#039;돋움&#039;, sans-serif;letter-spacing:-.02em;background-color:rgb(255,255,255);&quot;&gt;&lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:2;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;text-align:justify;&quot;&gt;모듈 선택: 클래스 디디 모듈을 선택하세요.&lt;/li&gt; &lt;li style=&quot;margin:10px 0px 10px 24px;padding:0px;font-size:14px;line-height:1.6em;font-family:&#039;Noto Sans KR&#039;, sans-serif;letter-spacing:-.02em;&quot;&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;line-height:2;letter-spacing:-.02em;text-align:justify;&quot;&gt;외부 모듈 사용: 이 값을 False로 변경하면 연결이 해제됩니다.&lt;/div&gt; &lt;div align=&quot;justify&quot; style=&quot;margin:0px;padding:0px;line-height:2;letter-spacing:-.02em;text-align:justify;&quot;&gt;기본값은 True이며 클래스 디디 모듈에 연결합니다.&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/832994</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/832994#comment</comments>			<pubDate>Tue, 03 Mar 2020 21:22:28 +0900</pubDate>
		</item><item>
			<title>만능 하드웨어 매크로 - 마우스 드래그 기능에 대한 팁.</title>
			<link>https://autolabs.co.kr/board_cFDS08/810257</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. 모바일 전용이 아닌 경우 마우스 드래그 기능은 자주 사용되죠? 하지만, 대부분의 매크로 프로그램들이 마우스 드래그 앤 드롭 기능을 잘 구현하지 못하고 있습니다. NGM 매크로도 드래그 앤 드롭이 윈도우에서 잘 동작하지 않는 경우가 있습니다. 일반적으로는 잘 동작하지만요^^;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;figure&gt;&amp;nbsp;&lt;/figure&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;마우스 드래그 앤 드롭 사용법에 대해서 알려드릴께요^^; 우선, NGM을 실행하세요. 아래 그림과 같이 새 스크립트를 만들고 마우스 다운과 업 액션을 추가해주세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;figure&gt;&lt;img data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot; src=&quot;https://k.kakaocdn.net/dn/EYsbt/btqz748Ii5S/TYBTKKLoiehB16zwWk4mK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FEYsbt%2Fbtqz748Ii5S%2FTYBTKKLoiehB16zwWk4mK0%2Fimg.png&quot; /&gt;&lt;/figure&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 동영상을 참고해서 그림판의 창 제목 부분을 다운으로 설정하고 이동할 위치는 업으로 설정합니다. 그리고 실행해보면 마우스가 정상 동작하지만 그림판은 이동이 안되는 것을 알 수 있습니다.&lt;/p&gt; &lt;p&gt;&lt;iframe allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot; height=&quot;407px&quot; scrolling=&quot;no&quot; src=&quot;https://www.youtube.com/embed/Sg2mQtutmF8?wmode=opaque&quot; width=&quot;720px&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;일부 프로그램들은 마우스가 점프하는걸 인지하지 못합니다. 그래서, 마우스 클릭 또는 다운이 되기전에 미리 마우스 이동이 되어 있어야 합니다. 아래와 같이 마우스 이동 옵션을 True로 변경한 후 다시 해보세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;figure&gt;&lt;img data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot; src=&quot;https://k.kakaocdn.net/dn/vUQDQ/btqz7Kbyrq0/C0dhoxRMIOqg3eF0sdI9dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FvUQDQ%2Fbtqz7Kbyrq0%2FC0dhoxRMIOqg3eF0sdI9dK%2Fimg.png&quot; /&gt;&lt;/figure&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이렇게해도 정상적으로 이동이 안되네요^^; 그렇다면 아래와 같이 실제 마우스 이동 액션을 추가하고 헤볼께요. 마우스 다운과 업 위에 이동 액션을 추가하세요. 그리고, 다운의 마우스 좌표를 복사해서 이동 좌표에 붙여넣기 합니다. 마우스 업도 동일하게 좌표를 설정해야겠죠?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;figure&gt;&lt;img data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot; src=&quot;https://k.kakaocdn.net/dn/sOsW4/btqz8nmCzs0/6k4nEuTqrK3YuqwIFVNkE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FsOsW4%2Fbtqz8nmCzs0%2F6k4nEuTqrK3YuqwIFVNkE0%2Fimg.png&quot; /&gt;&lt;/figure&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;실행하면 아래 동영상처럼 정상 동작하는 것을 확인할 수 있습니다. 보통은 마우스 다운과 마우스 업의 좌표를 다르게 해주면 마우스 드래그 앤 드롭이 됩니다. 하지만, 일부 프로그램들은 마우스 동작 전 해당 위치로 먼저 가 있어야 합니다. 비활성 모드에서도 비슷하게 처리하면 동작되니 테스트 해보시기 바랍니다^^;&lt;/p&gt; &lt;p&gt;&lt;iframe allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot; height=&quot;407px&quot; scrolling=&quot;no&quot; src=&quot;https://www.youtube.com/embed/YL-r-8pjn60?wmode=opaque&quot; width=&quot;720px&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/810257</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/810257#comment</comments>			<pubDate>Sun, 01 Dec 2019 08:52:10 +0900</pubDate>
		</item><item>
			<title>데이타베이스 시각화 도구 기능 개선. (파일 저장 및 프린트)</title>
			<link>https://autolabs.co.kr/board_cFDS08/802057</link>
				<description>&lt;p&gt;업무에 자동화를 사용하다보면 데이타베이스를 이용할일이 많습니다. 어떤 결과를 데이타베이스에 저장하고 시각화 도구를 통해 Excel, CSV, Text, Xml 파일로 저장하거나 바로 프린트할수도 있습니다. 리포트에 대한 요구가 점점 늘어나고 있어서 기능을 개선하거나 추가하는 방향으로 가야 할듯 합니다. 리포팅 관련해서 기능이 필요하다면 정리해서 요청해주세요.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지 5.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/057/802/bb760e37093aa61331d5eb0742c6964b.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/802057</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/802057#comment</comments>			<pubDate>Sat, 26 Oct 2019 11:52:29 +0900</pubDate>
		</item><item>
			<title>하드웨어 매크로 사용시 아두이노 에러 대처 방법.</title>
			<link>https://autolabs.co.kr/board_cFDS08/798063</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. 하드웨어 매크로로 사용할 때 아두이노를 이용합니다. 오픈마켓에서 7,000원~10,000원이면 하나 구매할 수 있으니 비싼 하드웨어(오토마우스, 오토키보드)를 사용하는것보단 이득이겠죠-_-ㅋ 기능도 훨씬 많으니까요~ NGM에서 아두이노에 소스코드를 업로드할 때 에러가 발생되는 경우가 있습니다. 아래처럼요.&lt;/p&gt; &lt;p&gt;&lt;b&gt;&amp;#39;Mouse&amp;#39; 가 없습니다. 스케치에서 &amp;#39;#include &amp;lt; Mouse.h&amp;gt;&amp;#39; 를 포함했나요?&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_2.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/827120/063/798/19e1d654349d834b9c0b916f0893a72a.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이런 에러 메시지가 아닌 포트를 찾을 수 없다고 나올수도 있습니다. 이 때는 아래 그림처럼 설정하고 다시 업로드하면 정상적으로 동작합니다.&lt;/p&gt; &lt;p&gt;메뉴의 툴 &amp;gt; 보드 &amp;gt; 아두이노 레오나르도 선택하세요.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지 3.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/827120/063/798/ac3d16b2dd7562f4bfd102aa978da6bb.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;메뉴의 툴 &amp;gt; 포트 &amp;gt; 아두이노 보드와 연결된 포트를 선택하세요. 아래 그림은 아두이노를 연결하지 않아서 포트가 안보이는데요. 여러분들은 포트가 COM1, COM3, COM5등등... 보일거예요.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지 4.png&quot; src=&quot;https://autolabs.co.kr/files/attach/images/827120/063/798/90c6ba4a53d03c7289bd4f270f61d5ee.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;보드와 포트를 설정했으면 업로드 해보세요. 정상적으로 작업이 완료됩니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/798063</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/798063#comment</comments>			<pubDate>Tue, 08 Oct 2019 19:23:23 +0900</pubDate>
		</item><item>
			<title>하드웨어 매크로 기능 개선.</title>
			<link>https://autolabs.co.kr/board_cFDS08/786960</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. 아래 코드는 NGM 5와 아두이노가 서로 연결되어 상호 작용할 수 있도록 하는 스케치 코드입니다. 이 내용을 전체 복사해서 붙여넣기 하고, 업로드하면 됩니다. 아두이노는 오픈마켓에서 약 7,000원이면 살 수 있어요~ 아래 코드를 아두이노에 붙여넣기 하고 NGM의 시리얼 포트 연결하면 하드웨어 방식으로 매크로를 동작시킬 수 있습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://autolabs.co.kr/index.php?mid=contents_IbVz51&amp;amp;_filter=search&amp;amp;search_target=title_content&amp;amp;search_keyword=%EC%95%84%EB%91%90%EC%9D%B4%EB%85%B8&amp;amp;document_srl=776660&quot; target=&quot;_blank&quot; title=&quot;새창으로 열림&quot;&gt;아두이노에 스케치&amp;nbsp;코드 업로드하는 방법 참고&lt;/a&gt;&lt;/b&gt;&amp;nbsp;]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt; &lt;p&gt;1&lt;/p&gt; &lt;p&gt;2&lt;/p&gt; &lt;p&gt;3&lt;/p&gt; &lt;p&gt;4&lt;/p&gt; &lt;p&gt;5&lt;/p&gt; &lt;p&gt;6&lt;/p&gt; &lt;p&gt;7&lt;/p&gt; &lt;p&gt;8&lt;/p&gt; &lt;p&gt;9&lt;/p&gt; &lt;p&gt;10&lt;/p&gt; &lt;p&gt;11&lt;/p&gt; &lt;p&gt;12&lt;/p&gt; &lt;p&gt;13&lt;/p&gt; &lt;p&gt;14&lt;/p&gt; &lt;p&gt;15&lt;/p&gt; &lt;p&gt;16&lt;/p&gt; &lt;p&gt;17&lt;/p&gt; &lt;p&gt;18&lt;/p&gt; &lt;p&gt;19&lt;/p&gt; &lt;p&gt;20&lt;/p&gt; &lt;p&gt;21&lt;/p&gt; &lt;p&gt;22&lt;/p&gt; &lt;p&gt;23&lt;/p&gt; &lt;p&gt;24&lt;/p&gt; &lt;p&gt;25&lt;/p&gt; &lt;p&gt;26&lt;/p&gt; &lt;p&gt;27&lt;/p&gt; &lt;p&gt;28&lt;/p&gt; &lt;p&gt;29&lt;/p&gt; &lt;p&gt;30&lt;/p&gt; &lt;p&gt;31&lt;/p&gt; &lt;p&gt;32&lt;/p&gt; &lt;p&gt;33&lt;/p&gt; &lt;p&gt;34&lt;/p&gt; &lt;p&gt;35&lt;/p&gt; &lt;p&gt;36&lt;/p&gt; &lt;p&gt;37&lt;/p&gt; &lt;p&gt;38&lt;/p&gt; &lt;p&gt;39&lt;/p&gt; &lt;p&gt;40&lt;/p&gt; &lt;p&gt;41&lt;/p&gt; &lt;p&gt;42&lt;/p&gt; &lt;p&gt;43&lt;/p&gt; &lt;p&gt;44&lt;/p&gt; &lt;p&gt;45&lt;/p&gt; &lt;p&gt;46&lt;/p&gt; &lt;p&gt;47&lt;/p&gt; &lt;p&gt;48&lt;/p&gt; &lt;p&gt;49&lt;/p&gt; &lt;p&gt;50&lt;/p&gt; &lt;p&gt;51&lt;/p&gt; &lt;p&gt;52&lt;/p&gt; &lt;p&gt;53&lt;/p&gt; &lt;p&gt;54&lt;/p&gt; &lt;p&gt;55&lt;/p&gt; &lt;p&gt;56&lt;/p&gt; &lt;p&gt;57&lt;/p&gt; &lt;p&gt;58&lt;/p&gt; &lt;p&gt;59&lt;/p&gt; &lt;p&gt;60&lt;/p&gt; &lt;p&gt;61&lt;/p&gt; &lt;p&gt;62&lt;/p&gt; &lt;p&gt;63&lt;/p&gt; &lt;p&gt;64&lt;/p&gt; &lt;p&gt;65&lt;/p&gt; &lt;p&gt;66&lt;/p&gt; &lt;p&gt;67&lt;/p&gt; &lt;p&gt;68&lt;/p&gt; &lt;p&gt;69&lt;/p&gt; &lt;p&gt;70&lt;/p&gt; &lt;p&gt;71&lt;/p&gt; &lt;p&gt;72&lt;/p&gt; &lt;p&gt;73&lt;/p&gt; &lt;p&gt;74&lt;/p&gt; &lt;p&gt;75&lt;/p&gt; &lt;p&gt;76&lt;/p&gt; &lt;p&gt;77&lt;/p&gt; &lt;p&gt;78&lt;/p&gt; &lt;p&gt;79&lt;/p&gt; &lt;p&gt;80&lt;/p&gt; &lt;p&gt;81&lt;/p&gt; &lt;p&gt;82&lt;/p&gt; &lt;p&gt;83&lt;/p&gt; &lt;p&gt;84&lt;/p&gt; &lt;p&gt;85&lt;/p&gt; &lt;p&gt;86&lt;/p&gt; &lt;p&gt;87&lt;/p&gt; &lt;p&gt;88&lt;/p&gt; &lt;p&gt;89&lt;/p&gt; &lt;p&gt;90&lt;/p&gt; &lt;p&gt;91&lt;/p&gt; &lt;p&gt;92&lt;/p&gt; &lt;p&gt;93&lt;/p&gt; &lt;p&gt;94&lt;/p&gt; &lt;p&gt;95&lt;/p&gt; &lt;p&gt;96&lt;/p&gt; &lt;p&gt;97&lt;/p&gt; &lt;p&gt;98&lt;/p&gt; &lt;p&gt;99&lt;/p&gt; &lt;p&gt;100&lt;/p&gt; &lt;p&gt;101&lt;/p&gt; &lt;p&gt;102&lt;/p&gt; &lt;p&gt;103&lt;/p&gt; &lt;p&gt;104&lt;/p&gt; &lt;p&gt;105&lt;/p&gt; &lt;p&gt;106&lt;/p&gt; &lt;p&gt;107&lt;/p&gt; &lt;p&gt;108&lt;/p&gt; &lt;p&gt;109&lt;/p&gt; &lt;p&gt;110&lt;/p&gt; &lt;p&gt;111&lt;/p&gt; &lt;p&gt;112&lt;/p&gt; &lt;p&gt;113&lt;/p&gt; &lt;p&gt;114&lt;/p&gt; &lt;p&gt;115&lt;/p&gt; &lt;p&gt;116&lt;/p&gt; &lt;p&gt;117&lt;/p&gt; &lt;p&gt;118&lt;/p&gt; &lt;p&gt;119&lt;/p&gt; &lt;p&gt;120&lt;/p&gt; &lt;p&gt;121&lt;/p&gt; &lt;p&gt;122&lt;/p&gt; &lt;p&gt;123&lt;/p&gt; &lt;p&gt;124&lt;/p&gt; &lt;p&gt;125&lt;/p&gt; &lt;p&gt;126&lt;/p&gt; &lt;p&gt;127&lt;/p&gt; &lt;p&gt;128&lt;/p&gt; &lt;p&gt;129&lt;/p&gt; &lt;p&gt;130&lt;/p&gt; &lt;p&gt;131&lt;/p&gt; &lt;p&gt;132&lt;/p&gt; &lt;p&gt;133&lt;/p&gt; &lt;p&gt;134&lt;/p&gt; &lt;p&gt;135&lt;/p&gt; &lt;p&gt;136&lt;/p&gt; &lt;p&gt;137&lt;/p&gt; &lt;p&gt;138&lt;/p&gt; &lt;p&gt;139&lt;/p&gt; &lt;p&gt;140&lt;/p&gt; &lt;p&gt;141&lt;/p&gt; &lt;p&gt;142&lt;/p&gt; &lt;p&gt;143&lt;/p&gt; &lt;p&gt;144&lt;/p&gt; &lt;p&gt;145&lt;/p&gt; &lt;p&gt;146&lt;/p&gt; &lt;p&gt;147&lt;/p&gt; &lt;p&gt;148&lt;/p&gt; &lt;p&gt;149&lt;/p&gt; &lt;p&gt;150&lt;/p&gt; &lt;p&gt;151&lt;/p&gt; &lt;p&gt;152&lt;/p&gt; &lt;p&gt;153&lt;/p&gt; &lt;p&gt;154&lt;/p&gt; &lt;p&gt;155&lt;/p&gt; &lt;p&gt;156&lt;/p&gt; &lt;p&gt;157&lt;/p&gt; &lt;p&gt;158&lt;/p&gt; &lt;p&gt;159&lt;/p&gt; &lt;p&gt;160&lt;/p&gt; &lt;p&gt;161&lt;/p&gt; &lt;p&gt;162&lt;/p&gt; &lt;p&gt;163&lt;/p&gt; &lt;p&gt;164&lt;/p&gt; &lt;p&gt;165&lt;/p&gt; &lt;p&gt;166&lt;/p&gt; &lt;p&gt;167&lt;/p&gt; &lt;p&gt;168&lt;/p&gt; &lt;p&gt;169&lt;/p&gt; &lt;p&gt;170&lt;/p&gt; &lt;p&gt;171&lt;/p&gt; &lt;p&gt;172&lt;/p&gt; &lt;p&gt;173&lt;/p&gt; &lt;p&gt;174&lt;/p&gt; &lt;p&gt;175&lt;/p&gt; &lt;p&gt;176&lt;/p&gt; &lt;p&gt;177&lt;/p&gt; &lt;p&gt;178&lt;/p&gt; &lt;p&gt;179&lt;/p&gt; &lt;p&gt;180&lt;/p&gt; &lt;p&gt;181&lt;/p&gt; &lt;p&gt;182&lt;/p&gt; &lt;p&gt;183&lt;/p&gt; &lt;p&gt;184&lt;/p&gt; &lt;p&gt;185&lt;/p&gt; &lt;p&gt;186&lt;/p&gt; &lt;p&gt;187&lt;/p&gt; &lt;p&gt;188&lt;/p&gt; &lt;p&gt;189&lt;/p&gt; &lt;p&gt;190&lt;/p&gt; &lt;p&gt;191&lt;/p&gt; &lt;p&gt;192&lt;/p&gt; &lt;p&gt;193&lt;/p&gt; &lt;p&gt;194&lt;/p&gt; &lt;p&gt;195&lt;/p&gt; &lt;p&gt;196&lt;/p&gt; &lt;/td&gt; &lt;td&gt; &lt;p&gt;#include&amp;nbsp;&amp;lt;Mouse.h&amp;gt;&lt;/p&gt; &lt;p&gt;#include&amp;nbsp;&amp;lt;Keyboard.h&amp;gt;&lt;/p&gt; &lt;p&gt;String&amp;nbsp;cmd&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;setup()&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;Serial.begin(9600);&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;loop()&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;cmd&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;char&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;while&amp;nbsp;(Serial.available())&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;Serial.read();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.concat(temp);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(cmd&amp;nbsp;!=&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;m&amp;nbsp;=&amp;nbsp;cmd.substring(0,&amp;nbsp;1);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;X&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(p,&amp;nbsp;0);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;Y&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(0,&amp;nbsp;p);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;V&amp;quot;&amp;nbsp;||&amp;nbsp;m&amp;nbsp;==&amp;nbsp;&amp;quot;H&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(0,&amp;nbsp;0,&amp;nbsp;p);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;K&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;c&amp;nbsp;=&amp;nbsp;cmd.substring(0,&amp;nbsp;2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;v&amp;nbsp;=&amp;nbsp;cmd.substring(2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LS&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_SHIFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RS&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_SHIFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LC&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_CTRL);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RC&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_CTRL);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LA&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_ALT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RA&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_ALT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;AL&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;AU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_UP_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;AR&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;AD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_DOWN_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;BS&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_BACKSPACE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;SB&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;&amp;#39;&amp;nbsp;&amp;#39;);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;TB&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_TAB);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;ET&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RETURN);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;EC&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_ESC);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;IT&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_INSERT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;DT&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_DELETE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;PU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_PAGE_UP);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;PD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_PAGE_DOWN);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;HM&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_HOME);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;ED&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_END);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;CL&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_CAPS_LOCK);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F1&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F1);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F2&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F3&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F3);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F4&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F4);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F5&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F5);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F6&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F6);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F7&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F7);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F8&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F8);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F9&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F9);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F10&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F10);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F11&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F11);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F12&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F12);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.press(v[0]);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.release(v[0]);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;c&amp;nbsp;=&amp;nbsp;cmd.toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(c)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;0:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;1:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;2:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;3:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;4:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;5:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;6:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;7:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;8:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;9:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;10:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;keyAction(String&amp;nbsp;c,&amp;nbsp;uint8_t&amp;nbsp;k)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.press(k);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.release(k);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot;&gt;Colored by Color Scripter&lt;/a&gt;&lt;/p&gt; &lt;/td&gt; &lt;td&gt;&lt;a href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot;&gt;cs&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위 코드는 키보드 기능이 모두 포함된건 아닙니다. 자주 사용하는 키보드만 추가되어 있으므로, 이외에 추가로 필요한 키보드 기능이 있으면 댓글로 남겨주세요. 계속해서 업데이트 하도록 하겠습니다.&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/786960</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/786960#comment</comments>			<pubDate>Wed, 21 Aug 2019 15:45:33 +0900</pubDate>
		</item><item>
			<title>외부 API - 시리얼 통신 - 연결 (External API, Serial Communication, Connection)</title>
			<link>https://autolabs.co.kr/board_cFDS08/779140</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다.&amp;nbsp; 오늘은 NGM 매크로를 하드웨어 방식으로 사용할 수 있도록 도와주는 시리얼 통신에 대해 알아보도록 하겠습니다. 이 기능이 필요한 이유는 일부 응용 프로그램이 소프트웨어 방식으로 동작하지 않기 때문입니다. 그래서, 아두이노나 라즈베리파이와 같은 장치가 필요하게 됩니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 예제는 아두이노 레오나르도 버전으로 진행됩니다. 이미 NGM 3 버전에서 설명한 내용이 있기 때문에 [&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://cafe.naver.com/ngmsoft/626&quot; target=&quot;_blank&quot; title=&quot;새창으로 열림&quot;&gt;NGM 3 하드웨어 방식으로 사용하기&lt;/a&gt;&lt;/b&gt;&amp;nbsp;] 를 읽어보고, 아두이노를 구매해야 합니다. 그리고 스케치를 통해 아두이노로 코드를 업로드하세요. 여기까지 완료 되었다면 아래 내용을 참고해서 간단한 테스트를 진행할 수 있게 됩니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;2215234F556EEB492F.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/140/779/0957b396a708c3b893267070182812ea.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;다운로드.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/140/779/61a19e21b79fae8840e425cf05144e0a.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림을 참고하여 스크립트에 시리얼 통신의 연결 액션을 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단에 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;시리얼 통신 카테고리에 연결 클릭&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_1.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/140/779/86ae7c2cf5f7fabd5e5ec5370a798bc6.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 액션은 특별히 매크로를 만들 때 필요한건 아닙니다. 이미 만들어진 스크립트를 동작시킬 때 소프트웨어 방식으로 할지 하드웨어 방식으로 할지 결정하는 문제입니다. 또한, 아두이노를 비롯한 외부 장치를 이용할때는 비활성모드로 사용할 수 없습니다. 당연한 이야기겠지만요^^;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;동작 테스트는 아래 동영상을 참고해주세요. 그리고, 동작에 문제가 있거나 아두이노 스케치 코드에 버그가 있으면 제보 바랍니다. 아두이노 코드는 사용자가 직접 작성해서 컴파이해도 됩니다.&lt;/p&gt; &lt;p&gt;&lt;iframe allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot; height=&quot;407px&quot; scrolling=&quot;no&quot; src=&quot;https://www.youtube.com/embed/Bw4feC22pUw?wmode=opaque&quot; width=&quot;720px&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_2.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/140/779/3632e3a52b4f67a7c4c47fcc81872198.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;마우스 동작&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;이동 거리: 하드웨어 방식으로 마우스를 이동할 때 거리를 설정합니다. 최대 이동 거리는 127이므로 1~127 사이의 값을 사용해야 합니다.&lt;/li&gt; &lt;li&gt;이동 속도: 0, 0 좌표에서 1270, 0 좌표로 이동한다면 127만큼 10번 이동합니다. 이 때 각각의 구간마다 딜레이를 설정합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;DTR 사용: 직렬 통신 동안 DTR(Data Terminal Ready) 신호를 사용할 수 있는지 설정합니다.&lt;/li&gt; &lt;li&gt;RTS 사용: 직렬 통신에 RTS(Request To Send) 신호를 사용할 수 있는지 설정합니다.&lt;/li&gt; &lt;li&gt;데이타 비트: 바이트 당 데이타 비트의 표준 길이를 가져오거나 설정합니다.&lt;/li&gt; &lt;li&gt;보레이트: 직렬 전송 속도를 가져오거나 설정합니다.&lt;/li&gt; &lt;li&gt;스톱 비트: 바이트 당 정지 비트의 표준 개수를 가져오거나 설정합니다.&lt;/li&gt; &lt;li&gt;시리얼 포트: 시리얼 통신에 사용할 포트를 선택합니다.&lt;/li&gt; &lt;li&gt;쓰기 타임아웃: 쓰기 작업을 마쳐야 하는 제한 시간(밀리초)를 가져오거나 설정합니다.&lt;/li&gt; &lt;li&gt;읽기 타임아웃: 읽기 작업을 마쳐야 하는 제한 시간(밀리초)를 가져오거나 설정합니다.&lt;/li&gt; &lt;li&gt;패리티: 패리티 검사 프로토콜을 가져오거나 설정합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/779140</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/779140#comment</comments>			<pubDate>Wed, 10 Jul 2019 08:27:13 +0900</pubDate>
		</item><item>
			<title>외부 API - 데이타베이스 - 읽기 (External API, Database, Read)</title>
			<link>https://autolabs.co.kr/board_cFDS08/778135</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. 이전 시간에 데이타베이스에 연결하는 방법에 대해 알아봤습니다. 오늘은 연결된 데이타베이스에서 어떻게 데이타를 가져오는지에 대해 알아보도록 하겠습니다. NGM은 전부 관계형 데이타베이스만 지원합니다. Oracle, MS-SQL, MySQL, MariaDB죠. 그렇기 때문에 질의문(Query)을 통해 CRUD(Create, Read, Update, Delete)를 만들어야 합니다. 하지만, 읽기 액션은 Read를 좀 더 쉽게 할 수 있도록 도와주는 액션입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 예제를 실행하기 위해서는 미리 데이타베이스에 연결되어 있어야 합니다. [&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://cafe.naver.com/ngmsoft/1043&quot; target=&quot;_blank&quot; title=&quot;새창으로 열림&quot;&gt;데이타베이스 연결 액션&lt;/a&gt;&lt;/b&gt;&amp;nbsp;] 또는 [&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://cafe.naver.com/ngmsoft/916&quot; target=&quot;_blank&quot; title=&quot;새창으로 열림&quot;&gt;데이타베이스 연결 옵션&lt;/a&gt;&lt;/b&gt;&amp;nbsp;] 내용을 먼저 학습해야 합니다. 우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;다운로드.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/5b0828133c73d7cc5dbb35e171fa1171.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림을 참고하여 스크립트에 데이타베이스의 읽기 액션을 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단에 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;데이타베이스 카테고리에 읽기 클릭&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_10.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/b1031d44b34708f2c2995cb99817d329.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림과 같이 속성을 눌러보세요. 자신의 컴퓨터에 설치되어 있는 데이터바이스나 또는 원격지의 데이타베이스의 테이블 목록을 확인할 수 있습니다. 아래 그림은 MS-SQL의 샘플 데이타베이스입니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;미리 연결된 데이타베이스가 있다면 이름이 표시됩니다.&lt;/li&gt; &lt;li&gt;테이블명을 클릭하면 연결된 데이타베이스의 테이블 목록이 표시됩니다.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_11.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/501dd45d2bf012fe7c81fdb8e76c504c.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;테이블을 선택하고, 스크립트 실행 버튼을 클릭하세요.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;카테고라이즈 테이블 선택&lt;/li&gt; &lt;li&gt;스크립트 실행 버튼 클릭&lt;/li&gt; &lt;li&gt;결과 테이블 확장&lt;/li&gt; &lt;li&gt;테이블 시각화 도구 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_13.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/5162500057dcfbe18e743f2d280f22b9.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;결과 테이블의 속성을 확장하면 기본적인 정보들을 확인할 수 있습니다. 또한, 시각화 도구를 클릭하면 아래 그림처럼 데이타를 직접 확인 가능합니다. 테이블의 스키마를 확인할 수 있고, 데이타도 볼 수 있습니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_14.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/5d68badaf35155588a01dfe6c83ecf14.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;물론, 결과 테이블에서 컬럼 목록을 확인할 수 있죠. 컬럼 목록은 SELECT와 WHERE에 사용됩니다. 그렇기 때문에 어떤 컬럼들이 있는지 확인하는게 중요하죠.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_15.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/81097da4c30f380c3dc2e951c389ba92.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;가져올 컬럼을 추가해볼까요? 아래 그림을 참고하여 컬럼을 선택합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;컬럼 목록을 클릭합니다.&lt;/li&gt; &lt;li&gt;ColumnItem 컬렉션 편집기에서 추가를 클릭하세요.&lt;/li&gt; &lt;li&gt;CategoryID 컬럼을 선택하세요.&lt;/li&gt; &lt;li&gt;확인을 눌러 작업을 완료하세요.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_16.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/fc6771381a9f0920494dee73740ba42b.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;다시 실행하고 가져온 데이타를 확인 해보세요. 아래 그림처럼 내가 선택한 컬럼의 데이타만 가져온 것을 확인할 수 있습니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;스크립트 실행 클릭&lt;/li&gt; &lt;li&gt;결과 데이타 클릭&lt;/li&gt; &lt;li&gt;가져온 데이타 확인&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_17.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/e42b1e1f1dca4c9b563ebde56f7b3423.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 내가 필요로하는 데이타만 추출하는 방법에 대해 알아보겠습니다. 위에서 가져온 내용을 보면 CategoryID가 1~8까지 있는 것을 알 수 있습니다. 2번만 가져오려면 어떻게 해야 할까요? 아래 그림처럼 조건 목록을 설정하면 됩니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;조건 목록 클릭&lt;/li&gt; &lt;li&gt;ParameterItem 컬렉션 편집기에서 추가 클릭&lt;/li&gt; &lt;li&gt;Column에 CategoryID 선택&lt;/li&gt; &lt;li&gt;Value에 &amp;quot;2&amp;quot; 입력&lt;/li&gt; &lt;li&gt;확인을 클릭하여 작업 완료&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_18.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/b46040b15f3a43c6cdf7269f6f0e6be4.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;스크립트를 다시 실행하고 결과 데이타를 확인해보세요. 조건 목록에 추가한대로 CategoryID가 2와 같은 데이타만 가져옵니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;스크립트 실행 클릭&lt;/li&gt; &lt;li&gt;결과 데이타 클릭&lt;/li&gt; &lt;li&gt;데이타베이스로부터 가져온 결과 내용 확인&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_19.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/2d17f9e1a54ef20e823084194898eddf.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_12.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/135/778/c293bb41619f2ab5eb50e3af85079f4f.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;데이터&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;결과 데이터: 데이타베이스에서 가져온 데이터를 표시합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;데이터 테이블 확장 기능&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;열 구분자: 결과 테이블을 저장할 때 텍스트 형식이라면 구분 문자열로 열을 처리합니다.&lt;/li&gt; &lt;li&gt;저장 옵션: 가져온 데이타를 파일로 저장하는 옵션입니다. Excel, CSV, Text, Xml을 지원합니다.&lt;/li&gt; &lt;li&gt;저장 위치: 파일이 저장되는 위치를 선택합니다.&lt;/li&gt; &lt;li&gt;행 구분자: 엑셀이 아닌 파일로 저장하는 경우 구분 문자열로 값을 행을 처리합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;조건 목록: 데이타를 가져오기 위한 조건을 설정합니다. 이 조건을 설정하지 않으면 모든 데이타를 가져옵니다.&lt;/li&gt; &lt;li&gt;컬럼 목록: 데이타를 가져올 컬럼을 설정합니다. 이 값을 설정하지 않으면 모든 컬럼을 가져옵니다.&lt;/li&gt; &lt;li&gt;테이블명: 데이타를 가져올 테이블을 선택합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/778135</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/778135#comment</comments>			<pubDate>Thu, 04 Jul 2019 18:08:52 +0900</pubDate>
		</item><item>
			<title>외부 API - FTP - 목록 (External API, FTP, File list)</title>
			<link>https://autolabs.co.kr/board_cFDS08/777888</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다.&amp;nbsp; 오늘은 FTP 관련 액션의 마지막인 목록 가져오기에 대해 알아볼께요. 이미 파일 업로드 다운로드는 배웠기 때문에 목록 가져오기와 Foreach 반복 액션을 조합하면 FTP 서버의 특정 폴더에 있는 모든 파일들을 다운로드할 수 있습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이번 내용은 단순히 파일 목록만 가져오는게 아닌 Foreach 반복과 배열을 이용해서 모든 파일을 한번에 다운로드하는 아주 어려운 예제입니다. 상당히 복합적인 사고가 필요하죠^^; 우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;다운로드.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/72ed456972c181c0dd489d126fec275d.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞의 FTP 연결과 끊기 메뉴얼을 참고해서 미리 서버에 연결되어 있어야 합니다. 그리고, 아래 그림을 참고하여 스크립트에 FTP 목록 액션을 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단에 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;FTP 카테고리에 목록 클릭&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;우측 하단에 속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_2.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/6fe271efebbefc4fd3df3af1bd25147c.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;목록을 가져와야 하므로, FTP서버에 아래처럼 파일을 5개 올려놓습니다. 내용이 없는 txt 파일을 5개 만들어서 서버로 미리 업로드 해두었습니다. 예제를 위해서 말이죠^^;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_30.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/78b01e738fa35f16b6a4d6d0878547ee.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;목록 액션의 속성을 아래 그림처럼 설정합니다. 하위 폴더가 없기 때문에 False로 설정하세요. 만약, 하위 폴더를 만들고 파일들을 넣어두었다면 True로 변경하면 됩니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;서버 경로에 파일들이 들어있는 폴더까지 경로를 입력 (루트에 있다면 &amp;quot;/&amp;quot;만 입력하면 됨)&lt;/li&gt; &lt;li&gt;하위 폴더는 False로 설정&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_3.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/7a4f298766ac96419c8f854fc1e99037.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;실행하면 아래 그림처럼 파일 목록을 표시해줍니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;스크립트에 추가한 목록 액션 클릭&lt;/li&gt; &lt;li&gt;속성의 데이터 카테고리에 있는 파일 목록 확장&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_3.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/237a8f81a969fe977d22fb83878b2c80.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;서버에 올린 파일 5개의 목록이 표시됩니다. 이렇게 FTP서버의 특정 폴더에 있는 파일 목록을 배열 형태로 가져올 수 있습니다. 이 파일들을 순차적으로 다운로드하려면 Foreach 반복을 사용합니다. 아래 그림처럼 Foreach 반복 액션을 추가하세요.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;좌측 하단에 함수 상자 탭 클릭&lt;/li&gt; &lt;li&gt;변수 추가 클릭&lt;/li&gt; &lt;li&gt;스크립트로 드래그 앤 드롭으로 추가&lt;/li&gt; &lt;li&gt;아이디에 &amp;quot;파일 목록&amp;quot; 입력&lt;/li&gt; &lt;li&gt;변수 형식은 배열(Array) 선택&lt;/li&gt; &lt;li&gt;함수의 Foreach 반복 클릭&lt;/li&gt; &lt;li&gt;스크립트로 드래그 앤 드롭으로 추가&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_31.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/a325da04affda5d73378ac4953270a89.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Foreach 반복에서 파일을 다운로드 해야하기 때문에 아래 그림처럼 FTP의 다운로드 액션을 추가해줍니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단의 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;FTP 카테고리의 다운로드 선택&lt;/li&gt; &lt;li&gt;스크립트로 드래그 앤 드롭으로 추가&lt;/li&gt; &lt;li&gt;속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_32.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/06408a9ed4d488f862661f902d8a81cb.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;목록에서 가져온 파일들을 변수에 저장시켜야 합니다. 그래야 Foreach 반복에서 사용할 수 있기 때문이죠~ 아래 그림을 참고하여 변수를 설정합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;스크립트의 목록 액션 선택&lt;/li&gt; &lt;li&gt;변수 추가하기 버튼 클릭&lt;/li&gt; &lt;li&gt;컬렉션 편집기에서 추가 클릭&lt;/li&gt; &lt;li&gt;데이터에 파일 목록 선택&lt;/li&gt; &lt;li&gt;변수 이름에 파일 목록 선택&lt;/li&gt; &lt;li&gt;확인을 클릭하여 작업 완료&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_33.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/ac28d0e0769c4789f60a9ae50074931a.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;파일 목록에서 파일명으로 반복해야 하기 때문에 파일명을 담을 변수를 아래 그림처럼 하나 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;변수 추가 선택&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;아이디에 &amp;quot;파일명&amp;quot; 입력&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_34.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/9e51c8fcb730564c1c871c22b6172ba4.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림처럼 Foreach 반복을 설정합니다. 그리고 변수에 저장된 파일 목록을 가져옵니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;스크립트에 추가한 Foreach 반복 선택&lt;/li&gt; &lt;li&gt;변수의 가져오기 클릭&lt;/li&gt; &lt;li&gt;컬렉션 편집기에서 추가 클릭&lt;/li&gt; &lt;li&gt;데이터에 배열 선택&lt;/li&gt; &lt;li&gt;변수 이름에 파일 목록 선택&lt;/li&gt; &lt;li&gt;확인을 클릭하여 작업 완료&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_35.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/afb226cb314510e07836e84a6b1dc7b8.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;파일명을 변수에 저장하기 위해 아래와 같이 설정합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Foreach 반복 선택&lt;/li&gt; &lt;li&gt;변수에 추가하기 클릭&lt;/li&gt; &lt;li&gt;컬렉션 편집기에서 추가 클릭&lt;/li&gt; &lt;li&gt;데이터에 아이템 선택&lt;/li&gt; &lt;li&gt;변수 이름에 파일명 선택&lt;/li&gt; &lt;li&gt;확인을 클릭하여 작업 완료&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_37.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/4f7319110a0630ded173034fc3c226d9.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림처럼 다운로드를 설정하세요.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;다운로드 액션 선택&lt;/li&gt; &lt;li&gt;파일을 다운로드 할 로컬 경로 선택 (바탕화면 선택)&lt;/li&gt; &lt;li&gt;변수의 가져오기 클릭&lt;/li&gt; &lt;li&gt;컬렉션 편집기의 추가 클릭&lt;/li&gt; &lt;li&gt;데이터에 서버 파일 전체 이름 선택&lt;/li&gt; &lt;li&gt;변수 이름에 파일명 선택&lt;/li&gt; &lt;li&gt;확인을 클릭하여 작업 완료&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_39.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/c07a785bca930f5580046285d2f97621.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;완성된 스크립트를 실행하면 아래 그림처럼 FTP서버에 있는 모든 파일을 바탕화면으로 다운로드 받게 됩니다. 여러분도 로컬 컴퓨터에 간단한 FTP서버를 구성하고 테스트 해보시길 바랍니다. FTP는 아주 오래된 기술이라서 관련 레퍼런스가 많습니다. 조금만 검색해보면 누구나 쉽고 빠르게 구성할 수 있을겁니다. 10개도 안되는 액션인데... 글이 엄청 길어져 버렸네요-_-;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;ezgif-1-8394baaa9b44.gif&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/d3a66ddf35746c6a11a3ed2dfbae509e.gif&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_5.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/888/777/a52d83ff88cbb0bf4f0cdb20232676b5.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;데이터&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;파일 목록: 지정한 폴더에 있는 파일의 목록을 표시합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;바이너리: FTP 서버로 파일을 다운로드할 때 바이너리 형식을 사용합니다.&lt;/li&gt; &lt;li&gt;서버 경로: 목록을 가져올 서버의 폴더 위치입니다.&lt;/li&gt; &lt;li&gt;패시브 모드: 클라이언트 응용 프로그램의 데이터 전송 프로세스를 패시브 모드로 사용합니다.&amp;nbsp;&lt;/li&gt; &lt;li&gt;하위 폴더: 이 값을 True로 설정하면 서버 경로 하위의 폴더의 파일도 모두 가져옵니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;패시브 모드란?&lt;/b&gt;&lt;/p&gt; &lt;p&gt;참고로, 패시브 모드를 사용하면 로컬 컴퓨터의 방화벽이 경고를 표시하지 않습니다. 이는 FTP에 대해 깊은 이해(?)가 있어야 합니다. 기본 값은 Active Mode입니다. Active Mode에서는 클라이언트가 서버에 파일을 업로드하거나 다운로드할 때 서버도 클라이언트에 접속 요청을 하게 됩니다. 그렇기 때문에 외부에서 들어오는 알 수 없는 서버에 대해 윈도우가 경고창을 표시하는 것입니다. 이 문제를 개선한 방식이 패시브 모드입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/777888</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/777888#comment</comments>			<pubDate>Wed, 03 Jul 2019 07:27:12 +0900</pubDate>
		</item><item>
			<title>외부 API - FTP - 업로드 (External API, FTP, Upload)</title>
			<link>https://autolabs.co.kr/board_cFDS08/777881</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다.&amp;nbsp; FTP 서버에 연결이 되었다면 파일을 업로드하거나 다운로드할 수 있어야 합니다. 서버에 연결한 계정이 업로드, 다운로드 권한이 있다면 말이죠^^; FTP 서버를 설정할 때 업로드와 다운로드 권한이 포함되어 있어야 이 테스트를 진행할 수 있습니다~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;다운로드.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/321b290b240d84d69852497ddd6fe06c.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞의 FTP 연결 메뉴얼을 참고해서 미리 서버에 연결되어 있어야 합니다. 그리고, 아래 그림을 참고하여 스크립트에 FTP 업로드 액션을 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단에 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;FTP 카테고리에 업로드 클릭&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;우측 하단에 속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_19.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/53f05f5ef4b34cd2f07066c1a1dc7708.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림을 참고하여 업로드 액션의 속성을 설정합니다. 그리고 실행 해보세요.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;로컬 파일에 업로드할 파일을 선택&lt;/li&gt; &lt;li&gt;FTP 서버의 계정이 할당받은 위치 입력&lt;/li&gt; &lt;li&gt;스크립트 실행 버튼 클릭&lt;/li&gt; &lt;li&gt;파일이 정상적으로 업로드 되었는지 확인&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_22.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/1b1fb465cff3c344cf88600cfb4c2b05.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;윈도우의 디펜더가 외부 접속에 대해 보안 경고창을 표시할 수 있습니다. 아래 내용을 천천히 잘 읽어보고 액세스를 허용할지 취소할지 선택해야 합니다. 이 테스트를 완료하려면 당연히 액세스 허용을 클릭해야 합니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_20.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/4dd047ed08820943e7047416405189b5.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 FTP 클라이언트(파일질라, 알FTP등등...)를 이용하여 서버에 접속합니다. 파일이 정상적으로 업로드 되었는지 확인할 수 있습니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_21.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/e75dcc3ca9de029d242d5ad30fdfc417.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_23.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/881/777/e41cef7f701ecf037a025fdeae941381.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;로컬 파일: FTP 서버에 업로드할 컴퓨터의 파일을 선택하세요.&lt;/li&gt; &lt;li&gt;바이너리: FTP 서버로 파일을 전송할 때 바이너리 형식을 사용합니다.&lt;/li&gt; &lt;li&gt;서버 경로: 파일이 저장될 서버의 폴더 위치입니다. 해당 위치에 권한이 필요합니다.&lt;/li&gt; &lt;li&gt;패시브 모드: 클라이언트 응용 프로그램의 데이터 전송 프로세스를 패시브 모드로 사용합니다.&amp;nbsp;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;패시브 모드란?&lt;/b&gt;&lt;/p&gt; &lt;p&gt;참고로, 패시브 모드를 사용하면 로컬 컴퓨터의 방화벽이 경고를 표시하지 않습니다. 이는 FTP에 대해 깊은 이해(?)가 있어야 합니다. 기본 값은 Active Mode입니다. Active Mode에서는 클라이언트가 서버에 파일을 업로드하거나 다운로드할 때 서버도 클라이언트에 접속 요청을 하게 됩니다. 그렇기 때문에 외부에서 들어오는 알 수 없는 서버에 대해 윈도우가 경고창을 표시하는 것입니다. 이 문제를 개선한 방식이 패시브 모드입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/777881</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/777881#comment</comments>			<pubDate>Wed, 03 Jul 2019 07:23:35 +0900</pubDate>
		</item><item>
			<title>외부 API - 데이타베이스 - 연결 (External API, Database, Connection)</title>
			<link>https://autolabs.co.kr/board_cFDS08/777576</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. 데이타베이스 액션에 대해 알아보는 첫번째 시간이군요. 우선, FTP와 원격 제어처럼 데이타베이스도 옵션에서 미리 접속해두고 관리할 수 있습니다. 스크립트를 실행할 때마다 매번 연결과 끊기를 사용하지 않아도 되는 편리함이 있죠~ 옵션의 데이타베이스 내용은 [&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://cafe.naver.com/ngmsoft/916&quot; target=&quot;_blank&quot; title=&quot;새창으로 열림&quot;&gt;여기&lt;/a&gt;&lt;/b&gt;&amp;nbsp;]를 참고하세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;옵션에 데이타베이스 설정을 사용하지 않는다면, 연결 액션을 통해 데이타베이스에 접속해야 합니다. 그래야, 나머지 액션들을 사용할 수 있거든요^^;&amp;nbsp;우선 간단한 테스트를 위해 아래와 같이 새로운 스크립트를 추가합니다.&lt;/p&gt; &lt;p&gt;&lt;b&gt;File &amp;gt; 새로 만들기 &amp;gt; 스크립트 (단축키: Ctrl+N)&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;다운로드.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/576/777/b10daebee20d92fe9f98cb376755f449.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래 그림을 참고하여 스크립트에 데이타베이스의 연결 액션을 추가합니다.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;우측 하단에 외부 API 탭 클릭&lt;/li&gt; &lt;li&gt;데이타베이스 카테고리에 연결 클릭&lt;/li&gt; &lt;li&gt;드래그 앤 드롭으로 스크립트에 추가&lt;/li&gt; &lt;li&gt;우측 하단에 속성 탭 클릭&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;img alt=&quot;이미지_1.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/576/777/af9ef015f716f9423905714d297e6b01.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;내용을 아래와 같이 설정합니다. 물론, 자신의 데이타베이스가 있어야 테스트를 완료할 수 있습니다. MSSQL, Oracle 또는 MySQL, MariaDB를 설치하거나 원격 서버에 있어야 합니다. 그리고, 설정은 데이타베이스 서버에 맞게 수정하고 테스트해야 합니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_4.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/576/777/6f9ca488c52b0d7761a9010a0a474377.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;속성 정보&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_5.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/576/777/f56e719d0f6070821e9e572f420a9ee6.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;b&gt;기본 작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;사용 여부: 이 액션의 사용 여부를 설정합니다. False로 설정하면 이 액션은 실행되지 않습니다.&lt;/li&gt; &lt;li&gt;설명: 이 액션의 부가적인 설명을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 전 지연: 이 액션이 실행되기 전 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;실행 후 지연: 이 액션이 실행된 후 지연 시간을 입력합니다.&lt;/li&gt; &lt;li&gt;아이디: 스크립트 내에서 유니크한 아이디를 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;데이터&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;파일 목록: 지정한 폴더에 있는 파일의 목록을 표시합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;가져오기: 글로벌 또는 로컬 변수에 저장되어 있는 값을 이 액션의 속성 값으로 가져옵니다.&lt;/li&gt; &lt;li&gt;추가하기: 이 액션의 속성 값을 글로벌 또는 로컬 변수에 저장합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;작업&lt;/b&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;공급자: 데이타베이스에 접속하는 공급자를 입력하세요. 공급자는 해당 데이타베이스 사이트에서 정보를 얻을 수 있습니다.&lt;/li&gt; &lt;li&gt;데이타 소스: 서버의 주소와 포트 또는 주소만 입력합니다.&lt;/li&gt; &lt;li&gt;데이타베이스: 데이타베이스를 선택합니다.&lt;/li&gt; &lt;li&gt;비밀번호: 데이타베이스에 접속하기 위한 계정의 비밀번호입니다.&lt;/li&gt; &lt;li&gt;사용자 아이디: 데이타베이스에 접속히 위한 계정의 아이디입니다.&lt;/li&gt; &lt;li&gt;초기 카탈로그: 데이타베이스의 이름을 입력합니다.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/777576</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/777576#comment</comments>			<pubDate>Tue, 02 Jul 2019 08:32:41 +0900</pubDate>
		</item><item>
			<title>NGM 3.0을 하드웨어 방식으로 사용하기. (Arduino with NGM)</title>
			<link>https://autolabs.co.kr/board_cFDS08/776660</link>
				<description>&lt;p&gt;안녕하세요. 소심비형입니다. NGM 3.0을 하드웨어 방식으로 사용할 수 있는 시리얼 통신 기능에 대해 알아보도록 하겠습니다. 우선, 아두이노 레오나르도를 하나 구매해야겠죠? 또는 가상 아두이노를 다운로드 받아서 설치 후 연습해봐도 됩니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;인터넷에 검색해보면 아두이노 레오나르도를 최저가에 구매할 수 있을겁니다. 대략 6,000원 선인거 같네요. 아무튼, 다른 제품이 아닌 레오나르도로 구입해야 합니다. 이유는, 레오나르도만 마우스, 키보드 모듈이 기본 장착되어 있기 때문입니다. 다른 제품은 직접 설치해야 하는데요. 아두이노는 메모리가 작아서 관리가 어렵고 복잡한 내용을 작성하기에는 어려움이 많기 때문입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;총알 배송으로 받은 아두이노 레오나르도를 컴퓨터에 연결합니다. 그러면, 아래 그림과 같은 프로그램이 실행되고 시리얼 포트도 자동으로 추가됩니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_1.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/660/776/470b1d1a35cd499f4c3afb533d0f81fd.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;NGM과 연동하기 위한 코드를 작성해야 합니다. 아래처럼요.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_2.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/660/776/cbb7c1e51950a64e4ab3d9d6672d85ae.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;코드는 정말 단순해서 NGM에서 제공하는 인터페이스만 맞으면 정상 동작하게 됩니다. 전체 코드는 아래에 있습니다.&lt;/p&gt; &lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt; &lt;p&gt;1&lt;/p&gt; &lt;p&gt;2&lt;/p&gt; &lt;p&gt;3&lt;/p&gt; &lt;p&gt;4&lt;/p&gt; &lt;p&gt;5&lt;/p&gt; &lt;p&gt;6&lt;/p&gt; &lt;p&gt;7&lt;/p&gt; &lt;p&gt;8&lt;/p&gt; &lt;p&gt;9&lt;/p&gt; &lt;p&gt;10&lt;/p&gt; &lt;p&gt;11&lt;/p&gt; &lt;p&gt;12&lt;/p&gt; &lt;p&gt;13&lt;/p&gt; &lt;p&gt;14&lt;/p&gt; &lt;p&gt;15&lt;/p&gt; &lt;p&gt;16&lt;/p&gt; &lt;p&gt;17&lt;/p&gt; &lt;p&gt;18&lt;/p&gt; &lt;p&gt;19&lt;/p&gt; &lt;p&gt;20&lt;/p&gt; &lt;p&gt;21&lt;/p&gt; &lt;p&gt;22&lt;/p&gt; &lt;p&gt;23&lt;/p&gt; &lt;p&gt;24&lt;/p&gt; &lt;p&gt;25&lt;/p&gt; &lt;p&gt;26&lt;/p&gt; &lt;p&gt;27&lt;/p&gt; &lt;p&gt;28&lt;/p&gt; &lt;p&gt;29&lt;/p&gt; &lt;p&gt;30&lt;/p&gt; &lt;p&gt;31&lt;/p&gt; &lt;p&gt;32&lt;/p&gt; &lt;p&gt;33&lt;/p&gt; &lt;p&gt;34&lt;/p&gt; &lt;p&gt;35&lt;/p&gt; &lt;p&gt;36&lt;/p&gt; &lt;p&gt;37&lt;/p&gt; &lt;p&gt;38&lt;/p&gt; &lt;p&gt;39&lt;/p&gt; &lt;p&gt;40&lt;/p&gt; &lt;p&gt;41&lt;/p&gt; &lt;p&gt;42&lt;/p&gt; &lt;p&gt;43&lt;/p&gt; &lt;p&gt;44&lt;/p&gt; &lt;p&gt;45&lt;/p&gt; &lt;p&gt;46&lt;/p&gt; &lt;p&gt;47&lt;/p&gt; &lt;p&gt;48&lt;/p&gt; &lt;p&gt;49&lt;/p&gt; &lt;p&gt;50&lt;/p&gt; &lt;p&gt;51&lt;/p&gt; &lt;p&gt;52&lt;/p&gt; &lt;p&gt;53&lt;/p&gt; &lt;p&gt;54&lt;/p&gt; &lt;p&gt;55&lt;/p&gt; &lt;p&gt;56&lt;/p&gt; &lt;p&gt;57&lt;/p&gt; &lt;p&gt;58&lt;/p&gt; &lt;p&gt;59&lt;/p&gt; &lt;p&gt;60&lt;/p&gt; &lt;p&gt;61&lt;/p&gt; &lt;p&gt;62&lt;/p&gt; &lt;p&gt;63&lt;/p&gt; &lt;p&gt;64&lt;/p&gt; &lt;p&gt;65&lt;/p&gt; &lt;p&gt;66&lt;/p&gt; &lt;p&gt;67&lt;/p&gt; &lt;p&gt;68&lt;/p&gt; &lt;p&gt;69&lt;/p&gt; &lt;p&gt;70&lt;/p&gt; &lt;p&gt;71&lt;/p&gt; &lt;p&gt;72&lt;/p&gt; &lt;p&gt;73&lt;/p&gt; &lt;p&gt;74&lt;/p&gt; &lt;p&gt;75&lt;/p&gt; &lt;p&gt;76&lt;/p&gt; &lt;p&gt;77&lt;/p&gt; &lt;p&gt;78&lt;/p&gt; &lt;p&gt;79&lt;/p&gt; &lt;p&gt;80&lt;/p&gt; &lt;p&gt;81&lt;/p&gt; &lt;p&gt;82&lt;/p&gt; &lt;p&gt;83&lt;/p&gt; &lt;p&gt;84&lt;/p&gt; &lt;p&gt;85&lt;/p&gt; &lt;p&gt;86&lt;/p&gt; &lt;p&gt;87&lt;/p&gt; &lt;p&gt;88&lt;/p&gt; &lt;p&gt;89&lt;/p&gt; &lt;p&gt;90&lt;/p&gt; &lt;p&gt;91&lt;/p&gt; &lt;p&gt;92&lt;/p&gt; &lt;p&gt;93&lt;/p&gt; &lt;p&gt;94&lt;/p&gt; &lt;p&gt;95&lt;/p&gt; &lt;p&gt;96&lt;/p&gt; &lt;p&gt;97&lt;/p&gt; &lt;p&gt;98&lt;/p&gt; &lt;p&gt;99&lt;/p&gt; &lt;p&gt;100&lt;/p&gt; &lt;p&gt;101&lt;/p&gt; &lt;p&gt;102&lt;/p&gt; &lt;p&gt;103&lt;/p&gt; &lt;p&gt;104&lt;/p&gt; &lt;p&gt;105&lt;/p&gt; &lt;p&gt;106&lt;/p&gt; &lt;p&gt;107&lt;/p&gt; &lt;p&gt;108&lt;/p&gt; &lt;p&gt;109&lt;/p&gt; &lt;p&gt;110&lt;/p&gt; &lt;p&gt;111&lt;/p&gt; &lt;p&gt;112&lt;/p&gt; &lt;p&gt;113&lt;/p&gt; &lt;p&gt;114&lt;/p&gt; &lt;p&gt;115&lt;/p&gt; &lt;p&gt;116&lt;/p&gt; &lt;p&gt;117&lt;/p&gt; &lt;p&gt;118&lt;/p&gt; &lt;p&gt;119&lt;/p&gt; &lt;p&gt;120&lt;/p&gt; &lt;p&gt;121&lt;/p&gt; &lt;p&gt;122&lt;/p&gt; &lt;p&gt;123&lt;/p&gt; &lt;p&gt;124&lt;/p&gt; &lt;p&gt;125&lt;/p&gt; &lt;p&gt;126&lt;/p&gt; &lt;p&gt;127&lt;/p&gt; &lt;p&gt;128&lt;/p&gt; &lt;p&gt;129&lt;/p&gt; &lt;p&gt;130&lt;/p&gt; &lt;p&gt;131&lt;/p&gt; &lt;p&gt;132&lt;/p&gt; &lt;p&gt;133&lt;/p&gt; &lt;p&gt;134&lt;/p&gt; &lt;p&gt;135&lt;/p&gt; &lt;p&gt;136&lt;/p&gt; &lt;p&gt;137&lt;/p&gt; &lt;p&gt;138&lt;/p&gt; &lt;p&gt;139&lt;/p&gt; &lt;p&gt;140&lt;/p&gt; &lt;p&gt;141&lt;/p&gt; &lt;p&gt;142&lt;/p&gt; &lt;p&gt;143&lt;/p&gt; &lt;p&gt;144&lt;/p&gt; &lt;p&gt;145&lt;/p&gt; &lt;p&gt;146&lt;/p&gt; &lt;p&gt;147&lt;/p&gt; &lt;p&gt;148&lt;/p&gt; &lt;p&gt;149&lt;/p&gt; &lt;p&gt;150&lt;/p&gt; &lt;p&gt;151&lt;/p&gt; &lt;p&gt;152&lt;/p&gt; &lt;p&gt;153&lt;/p&gt; &lt;p&gt;154&lt;/p&gt; &lt;p&gt;155&lt;/p&gt; &lt;p&gt;156&lt;/p&gt; &lt;p&gt;157&lt;/p&gt; &lt;p&gt;158&lt;/p&gt; &lt;p&gt;159&lt;/p&gt; &lt;p&gt;160&lt;/p&gt; &lt;p&gt;161&lt;/p&gt; &lt;p&gt;162&lt;/p&gt; &lt;p&gt;163&lt;/p&gt; &lt;p&gt;164&lt;/p&gt; &lt;p&gt;165&lt;/p&gt; &lt;p&gt;166&lt;/p&gt; &lt;p&gt;167&lt;/p&gt; &lt;p&gt;168&lt;/p&gt; &lt;p&gt;169&lt;/p&gt; &lt;p&gt;170&lt;/p&gt; &lt;p&gt;171&lt;/p&gt; &lt;p&gt;172&lt;/p&gt; &lt;/td&gt; &lt;td&gt; &lt;p&gt;#include&amp;nbsp;&amp;lt;Mouse.h&amp;gt;&lt;/p&gt; &lt;p&gt;#include&amp;nbsp;&amp;lt;Keyboard.h&amp;gt;&lt;/p&gt; &lt;p&gt;String&amp;nbsp;cmd&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;setup()&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;Serial.begin(9600);&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;loop()&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;cmd&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;char&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;while&amp;nbsp;(Serial.available())&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;Serial.read();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.concat(temp);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(cmd&amp;nbsp;!=&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;m&amp;nbsp;=&amp;nbsp;cmd.substring(0,&amp;nbsp;1);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;X&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(p,&amp;nbsp;0);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;Y&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(0,&amp;nbsp;p);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;V&amp;quot;&amp;nbsp;||&amp;nbsp;m&amp;nbsp;==&amp;nbsp;&amp;quot;H&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;p&amp;nbsp;=&amp;nbsp;cmd.substring(1).toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.move(0,&amp;nbsp;0,&amp;nbsp;p);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(m&amp;nbsp;==&amp;nbsp;&amp;quot;K&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;c&amp;nbsp;=&amp;nbsp;cmd.substring(0,&amp;nbsp;2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;v&amp;nbsp;=&amp;nbsp;cmd.substring(2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LeftShiftKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_SHIFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RightShiftKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_SHIFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LeftControlKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_CTRL);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RightControlKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_CTRL);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LeftAltKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_ALT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RightAltKey&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_ALT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;LeftArrow&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_LEFT_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;UpArrow&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_UP_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;RightArrow&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RIGHT_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;DownArrow&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_DOWN_ARROW);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;Backspace&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_BACKSPACE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;Tab&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_TAB);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;Enter&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_RETURN);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;CapsLock&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_CAPS_LOCK);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F1&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F1);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F2&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F2);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F3&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F3);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F4&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F4);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F5&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F5);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F6&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F6);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F7&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F7);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F8&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F8);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F9&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F9);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F10&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F10);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F11&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F11);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(v&amp;nbsp;==&amp;nbsp;&amp;quot;F12&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyAction(c,&amp;nbsp;KEY_F12);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.press(v[0]);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.release(v[0]);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;c&amp;nbsp;=&amp;nbsp;cmd.toInt();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(c)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;0:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;1:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;2:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;3:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;4:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;5:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;6:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_RIGHT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;7:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;8:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.click(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;9:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.press(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;10:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mouse.release(MOUSE_MIDDLE);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;void&amp;nbsp;keyAction(String&amp;nbsp;c,&amp;nbsp;uint8_t&amp;nbsp;k)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KD&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.press(k);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(c&amp;nbsp;==&amp;nbsp;&amp;quot;KU&amp;quot;)&amp;nbsp;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Keyboard.release(k);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;}&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot;&gt;Colored by Color Scripter&lt;/a&gt;&lt;/p&gt; &lt;/td&gt; &lt;td&gt;&lt;a href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot;&gt;cs&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위 코드를 아두이노에 붙여넣기 한 후 업로드 버튼을 클릭하세요. 간략하게 코드에 대해 설명하면, NGM에서 시리얼로 변환 해주는 인터페이스들을 스케치로 코드화한 내용입니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_3.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/660/776/1589639dbad1c4a51ca3eca462069bb7.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;스케치가 컴파일중입니다.&lt;/p&gt; &lt;p&gt;&lt;img alt=&quot;이미지_4.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/660/776/9be98e121eaf41160be0819ac0ded426.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;컴파일된 코드가 아두이노로 업로드 되었습니다.&lt;br /&gt; &lt;img alt=&quot;이미지_5.png&quot; src=&quot;https://autolabs.co.kr/./files/attach/images/827120/660/776/9ed5c30931910118130c1ab23d8f6f7f.png&quot; /&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 NGM을 실행한 후 아래 동영상처럼 설정합니다.&lt;/p&gt; &lt;p&gt;&lt;iframe allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot; height=&quot;407px&quot; scrolling=&quot;no&quot; src=&quot;https://www.youtube.com/embed/Bw4feC22pUw?wmode=opaque&quot; width=&quot;720px&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위 영상을 보면 아시겠지만, 하드웨어적으로 입력되는건 기존 매크로처럼 마우스가 순간 이동되지 않습니다. 물론, 비활성 매크로도 안됩니다. 따라서, 마우스의 최대 속도인 127만큼만 이동이 되며, 거리를 자동으로 계산하여 이동시켜줍니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;추천, 구독, 홍보&lt;/b&gt;&amp;nbsp;꼭~ 부탁드립니다.&lt;/p&gt; &lt;p&gt;여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~&lt;/p&gt; &lt;p&gt;감사합니다~&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>소심비형</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/776660</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/776660#comment</comments>			<pubDate>Thu, 27 Jun 2019 16:21:07 +0900</pubDate>
		</item><item>
			<title>안녕하세요...</title>
			<link>https://autolabs.co.kr/board_cFDS08/615706</link>
				<description>요즘 개인적인 일때문에 방문이 뜸했네요&lt;br /&gt; 홈페이지도 조금 단장 하신듯하고...&lt;br /&gt; 화원분들 HID에 관심이 많은덧 같더라구요...&lt;br /&gt; 쪽지가 많이 와있어서 깜짝 놀랐습니다. &lt;br /&gt;&lt;br /&gt; 추신 누가 리니지1문의 하시던데 오핫으로 별다른 우회없이도 가능합니다&lt;br /&gt; 오핫 버전의 차이일뿐....요즘은 모르겠지만 한6개월 전인가까진...&lt;br /&gt;&lt;br /&gt; 그럼 즐거운 하루 보내세요.</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>용가리맨</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/615706</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/615706#comment</comments>			<pubDate>Mon, 03 Jul 2017 18:08:16 +0900</pubDate>
		</item><item>
			<title>WDK 설치 및 VS 2010으로 개발환경 구축하기.</title>
			<link>https://autolabs.co.kr/board_cFDS08/584187</link>
				<description>&lt;p&gt; 안녕하세요, MFC 어플리케이션 레벨에서 2년정도 재직중인 초짜 프로그래머입니다.&lt;/p&gt; &lt;p&gt;최근 가상 휴먼 인터페이스 장치(VHID)의 매력에 홀려(?)서 공부를 시작하게되었습니다.&lt;/p&gt; &lt;p&gt; 먼저, 이런 포럼을 만드시고 관리해주시어, 못난 중생에게 공부할수 있는 환경을 만들어주신&lt;/p&gt; &lt;p&gt;관리자분께 정말 감사드립니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; 이 학문에 입문을 하기 전에, 무슨 개발환경에서 어떻게 개발을 시작해야하는가..의 문제에 봉착하게 되었습니다.&lt;/p&gt; &lt;p&gt;웹에서 여러 문서를 뒤적거리던 중, 발견한 &lt;strong&gt;&quot;WDK 설치 및 Visual studio 2010에서 개발 환경을 만드는 방법&quot; &lt;/strong&gt;을 공유드립니다.&lt;/p&gt; &lt;p&gt;(역시, Visual studio에서 편집하고 컴파일 하는것이 편할 거야... 라는 개인적인 생각에 찾아보았습니다.)&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[1. WDK 7 다운로드.]&lt;/p&gt; &lt;p&gt; Window Driver kit(이하 WDK)는 &lt;strong&gt;Windows 7&lt;/strong&gt;, Windows Vista, Windows XP, Windows Server 2008 R2, Windows Server 2008, and Windows Server 2003 의 OS에서 Driver를 개발하기 위한 개발도구입니다. (하기 링크 내용 참조)&lt;/p&gt; &lt;p&gt; 링크 : https://www.microsoft.com/en-us/download/details.aspx?id=11800&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[2. 빌드 배치파일 다운로드 및 편집]&lt;/p&gt; &lt;p&gt; 첨부된 파일 배치파일을 받아주시고, 배치파일의 14번줄의 내용, WDK가 설치된 폴더경로를 수정합니다.&lt;/p&gt; &lt;p&gt; set WIN7BASE=C:\WinDDK\7600.16385.1&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[3. 편집한 배치파일을 Visual Studio 2010 설치 경로에 이동]&lt;/p&gt; &lt;p&gt;ex Path : C:\Program Files(x64)\Microsoft Visual Studio 10.0\VC\bin&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[4. 프로젝트 생성 및 속성 설정]&lt;/p&gt; &lt;p&gt; 1) Visual Studio 2010을 실행합니다.&lt;/p&gt; &lt;p&gt; 2) 새 프로젝트 &amp;gt; Visual C++(일반) &amp;gt; 메이크 파일 프로젝트를 선택하여 프로젝트를 생성 마법사를 시작합니다.&lt;/p&gt; &lt;p&gt; 3) 디버그 구성 설정.&lt;/p&gt; &lt;p&gt; 빌드 명령줄 : ddkbuild -WIN7 checked .&lt;br /&gt; 다시 빌드 명령줄 : ddkbuild -WIN7 checked . -cZ&lt;/p&gt; &lt;p&gt; 4) 릴리즈 구성 설정.&lt;/p&gt; &lt;p&gt; 빌드 명령줄 : ddkbuild -WIN7 free .&lt;br /&gt; 다시 빌드 명령줄 : ddkbuild -WIN7 free . -cZ&lt;/p&gt; &lt;p&gt; 5) 포함 디렉토리 및 라이브러리 디렉토리 설정.&lt;/p&gt; &lt;p&gt; &amp;lt;포함 디렉토리 설정&amp;gt;&lt;/p&gt; &lt;p&gt; c:\WinDDK\7600.16385.1\inc\api&lt;/p&gt; &lt;p&gt; c:\WinDDK\7600.16385.1\inc\mfc42&lt;/p&gt; &lt;p&gt; c:\WinDDK\7600.16385.1\inc\ddk&lt;/p&gt; &lt;p&gt; &amp;lt;라이브러리 디렉토리 설정&amp;gt;&lt;/p&gt; &lt;p&gt; c:\WinDDK\7600.16385.1\lib\win7\i386&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[5. 소스파일 작성]&lt;/p&gt; &lt;p&gt;/*driver.c*/&lt;/p&gt; &lt;p&gt;#include &amp;lt;ntddk.h&amp;gt;&lt;/p&gt; &lt;p&gt;VOID SIMPLE_Unload(IN PDRIVER_OBJECT DriverObject)&lt;br /&gt; {&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)&lt;br /&gt; {&lt;br /&gt; NTSTATUS returnStatus = STATUS_SUCCESS;&lt;/p&gt; &lt;p&gt; DriverObject-&amp;gt;DriverUnload = SIMPLE_Unload;&lt;br /&gt; return returnStatus;&lt;br /&gt; }&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[6. MAKEFILE, SOURCES 수정 및 컴파일]&lt;/p&gt; &lt;p&gt; 1) 첨부된 파일중 MAKEFILE과 SOURCES파일을 프로젝트 폴더에 넣으시고, 내용을 다음과 같이 수정합니다.&lt;/p&gt; &lt;p&gt; TARGETNAME=ddktest //컴파일 후, 생성될 .sys 파일의 이름 &lt;br /&gt; TARGETPATH=obj&lt;br /&gt; TARGETTYPE=DRIVER&lt;br /&gt; SOURCES=driver.c //9번에서 작성한 소스파일의 이름으로 변경한다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; 2) 이제 컴파일을 하시면, ddktest.sys 파일이 생성됩니다.&lt;/p&gt; &lt;p&gt; &amp;lt;생성 경로&amp;gt;&lt;/p&gt; &lt;p&gt; 릴리즈 빌드 : 프로젝트 폴더\objfre_win7_x86\i386\&lt;/p&gt; &lt;p&gt; 디버그 빌드 : 프로젝트 폴더\objchk_win7_x86\i386\&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; 저는 이제 시작입니다. 많은 도움 부탁드립니다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;감사합니다.&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>	<category>WDK</category><category>VS2010</category>			<dc:creator>Hello_WDK</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/584187</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/584187#comment</comments>			<pubDate>Sat, 07 Jan 2017 18:13:40 +0900</pubDate>
		</item><item>
			<title>오토핫키로 엑셀 작업하기!2 ( 최대 행,열 구하기 )</title>
			<link>https://autolabs.co.kr/board_cFDS08/576899</link>
				<description>&lt;p&gt;이전에는 Cell에 있는 값들을 R/W하는 작업들을 간단하게 올렸습니다.&lt;/p&gt; &lt;p&gt;그렇다면 R/W를 하는데에서 필요한 정보가 무엇이 있을까 생각해보았습니다.&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#0000CD;&quot;&gt;엑셀데이터의 양이 많아 분류를 하는 작업&lt;/span&gt;&lt;/p&gt; &lt;p&gt;가장 많이 하는 작업인것 같습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;분류를 하는 방식은 사람마다 많이 다르겠지만 여기서는 분류방식이 아닌&lt;/p&gt; &lt;p&gt;필요한 값들을 구하는 방법을 찾아보겠습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;먼저 이전에 다루었던 내용을 통해서 구현을 한다면&lt;/p&gt; &lt;p&gt;Cell을 사용 하는 방법이 가장 좋겠죠&lt;/p&gt; &lt;p&gt;Range를 사용하면 Rows는 구할지언정 Columns는&amp;nbsp;구하기 힘들어지죠...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;하지만 역시나 MS!!!좋은 기능이 있습니다..&lt;/p&gt; &lt;p&gt;바로 최대Rows,Columns를 구하는 기능인데요.&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;endRow := Excel.ActiveSheet.UsedRange.Rows.Count&amp;nbsp;&lt;br /&gt; endCol := Excel.ActiveSheet.UsedRange.Columns.Count&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;이라는 커멘드를 통해서 한번에 구할 수 있습니다.!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다면 이후는 루프문을 통해서 쉽게 구현이 가능해지죠!&lt;/p&gt; &lt;p&gt;&lt;br /&gt; XLS_file_path3 := A_WorkingDir . &amp;quot;\매입매출2.xls&amp;quot;&lt;br /&gt; Excel := ComObjActive(&amp;quot;Excel.Application&amp;quot;)&lt;br /&gt; Excel Workbooks.Open(XLS_file_path3) ;open an existing file&lt;br /&gt; Excel .Workbooks.Add&lt;br /&gt; Excel .Visible:=false&lt;/p&gt; &lt;p&gt;endRow := Excel.ActiveSheet.UsedRange.Rows.Count&lt;br /&gt; Loop %endRow%&lt;br /&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;작업&lt;br /&gt; }&lt;br /&gt; endCol := 엑셀03.ActiveSheet.UsedRange.Columns.Count&lt;br /&gt; Loop %endCol%&lt;br /&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;작업&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; ;;저장&lt;br /&gt; Excel .ActiveWorkbook.Save()&lt;/p&gt; &lt;p&gt;;;닫기&lt;br /&gt; 엑셀03.ActiveWorkBook.Close&lt;br /&gt; 엑셀03.Quit&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>	<category>오토핫키로</category><category>엑셀</category><category>작업하기!2</category><category>(</category><category>최대</category><category>행</category><category>열</category><category>구하기</category><category>)</category>			<dc:creator>Info</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/576899</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/576899#comment</comments>			<pubDate>Tue, 29 Nov 2016 00:49:13 +0900</pubDate>
		</item><item>
			<title>오토핫키로 엑셀 작업하기! (엑셀 기본)</title>
			<link>https://autolabs.co.kr/board_cFDS08/576774</link>
				<description>&lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;먼저 엑셀 열고 닫기&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Indexpath:= &amp;nbsp;A_WorkingDir . &amp;quot;\Excel\Index.xlsx&amp;quot;&amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; IndexExcel := ComObjCreate(&amp;quot;Excel.Application&amp;quot;) ;오브젝트생성&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;IndexExcel.Workbooks.Open(Indexpath) ;엑셀열기&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;IndexExcel.Visible:=false ;true &amp;nbsp; &amp;nbsp; ;육안으로 보이게할지 설정&lt;br /&gt; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;IndexExcel.ActiveWorkbook.Save() ;저장&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;IndexExcel.ActiveWorkBook.Close &amp;nbsp;;닫기&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;IndexExcel.Quit ;오브젝트종료&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;Indexpath 엑셀파일의 경로입니다.(절대경로 상대경로 상관없습니다.)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;데이터 읽기,쓰기&lt;/p&gt; &lt;p&gt;데이터를 읽고 쓰는데는 2가지 방법이 있습니다&lt;/p&gt; &lt;p&gt;참조형에 따라 나뉘는데요&lt;/p&gt; &lt;p&gt;일반적으로 사용하는 기본참조형(A1)&lt;/p&gt; &lt;p&gt;일반적인 참조형은 변수의 값중에 A~ZZ등등..알파벳이들어있어&lt;/p&gt; &lt;p&gt;증,감시 번거로움이 있습니다.&lt;/p&gt; &lt;p&gt;하지만 정확한 위치로 이동 할 수 있다는 편리함이 있죠.&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;IndexExcel .Range(&amp;quot;S3&amp;quot;).Value&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;해당 엑셀 값을 읽어오는 경우에는&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;변수:=IndexExcel .Range(&amp;quot;S3&amp;quot;).Value &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;해당 엑셀 값을 쓰는 경우에는&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;IndexExcel .Range(&amp;quot;S3&amp;quot;).Value:=데이터&lt;/span&gt;&lt;/p&gt; &lt;p&gt;변수로 컨트롤 할 수 있는 R1C1참조형&lt;/p&gt; &lt;p&gt;이경우에는 변수로 대체할 수 있어서 편리합니다.&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp; &amp;nbsp; IndexExcel .Cells(Row,Cul).Value&lt;/span&gt;&lt;/p&gt; &lt;p&gt;사용법은 위와 같습니다&lt;/p&gt; &lt;p&gt;B1에 데이터를 읽어오는 경우&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp; &amp;nbsp; 변수 := IndexExcel .Cells(1,2).Value&lt;/span&gt;&lt;/p&gt; &lt;p&gt;A2에 데이터를 쓰는 경우&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp; &amp;nbsp; IndexExcel .Cells(2,1).Value := 데이터&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;하지만 모든 데이터를 한번에 읽어와서 문제가 없으면...고생을 하지 않죠..&lt;/p&gt; &lt;p&gt;문자열의 데이터는 상관없습니다!&lt;/p&gt; &lt;p&gt;단,숫자일 경우....상수여도 소숫점까지 가져오는 불쌍사가 생겨버리게 되죠...&lt;/p&gt; &lt;p&gt;이경우에는 딱 두줄의 코드를 추가함으로서 해결이 가능합니다&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#FF0000;&quot;&gt;변수 := IndexExcel .Cells(1,2).Value&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color:#FF0000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SetFormat,FLOAT,0.0&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 변수+=0&lt;/span&gt;&lt;/p&gt; &lt;p&gt;이렇게 해주면 짜쟌~ 상수로 출력이 가능합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오늘은...시간이 없어서 간단하게 몇자 적고갑니다!&lt;/p&gt; &lt;p&gt;나중에 추가로 올릴게요!&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>자료</category>	<category>오토핫키로</category><category>엑셀</category><category>작업하기!</category><category>(엑셀</category><category>기본)</category>			<dc:creator>Info</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/576774</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/576774#comment</comments>			<pubDate>Mon, 28 Nov 2016 19:15:12 +0900</pubDate>
		</item><item>
			<title>가상키보드 마우스를 제작 후기(펌)</title>
			<link>https://autolabs.co.kr/board_cFDS08/441228</link>
				<description>&lt;p&gt;&lt;strong&gt;글을 읽다보면 뭔가 힌트가 조금 보이는듯 합니다 ㅎ&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;드디어 완성도가 꽤 높은 가상키보드 마우스를 만들었다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;가상장치에 관심이 많았지만... 어디서 부터 손을 대야 할지 몰라서..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;나름 활용도도 높고 쉽게 보이는 키보드 마우스 부터 시작해 보기로 했다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헐~~ 그런데.. 키보드 마우스를 가상화 하는것이 쉬운일이 아니다...&lt;/p&gt; &lt;p&gt;(잘못 골랐나? 하는 생각이 들 정도로 어렵고 막연했다... )&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;한번 하기로 마음을 먹었으니.. 어떻게든 완성해 보기로 했다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;웹서핑을 열나게 하는데..&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.secret.pe.kr/19096&quot; target=&quot;_blank&quot;&gt;http://www.secret.pe.kr/19096&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위의 싸이트를 찾았다... 헐~~ 대박... 가상키보드 마우스를 만들던 노하우가 그데로 다 있었다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;글쓴이가&amp;nbsp;AmesianX 라는 것 같은데.. 이분이 정리해 놓은 길을 그데로 가기로 했다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;첫번째로 DDK를 설치했다. 내가 설치한 버젼은 [7600.16385.1]&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;두번째로 vhidmini 라는 예제를 찾아보았다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐 내가 설치한 버젼에는 vhidmini라는 예제가 없었다... 젠장!! 된장.....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그래서 vhidmini를 찾기 위해서 또 웹서핑을 했다... 내가 좀 무식한 관계로....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;DDK 버젼이 낮은것을 어디서 다운받았다. 버젼이 얼마였는지... 기억이 안난다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;낮은 버젼에는 vhidmini 예제가 있었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그 소스만 쏙~ 빼고 지웠던것 같다...드디어 vhidmini소스를 구했다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 웹서핑 과정에서 더 대박...&amp;nbsp;&lt;/font&gt;AmesianX&amp;nbsp;이라는 분이 직접 구현한 소스를 다운로드 받았다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;AmesianX&amp;nbsp;님께서 만든 소스를 시현해 보았다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 잘된다... 한가지 흠이 있다면... 키보드 속도가 엄청 느리다는 것이었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그렇더라도 그 소스를 토대로 기존의 vhidmini와 비교 해가면서 어떤 부분을 수정했는지...&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;분석을 했다...&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;분석결과&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;DDK에서 제공하는 vhidmini는 깡통이었다... 설치를 하면 키보드, 마우스 이런거는 없고&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;단순히 HID root 장치를 설치하는 수준이었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헌데&amp;nbsp;&lt;/font&gt;AmesianX&amp;nbsp;소스는 여기에 키보드,마우스 디스크립터를 추가했다는 점이 달랐고...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;어플리케이션과 통신을 할때 IPC의 일종인 Named Pipe 로 통신을 한다는 것이 추가 되었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;AmesianX&amp;nbsp;께서 제작한 소스가&amp;nbsp;&lt;font face=&quot;Gulim, Arial&quot;&gt;왜? 키보드 속도가 느린지... 분석에 들어갔다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;속도만 느리면 다행인데... 키 값을 연속으로 빠르게 줘 버리면 몇개 까먹어 버린다는.. ㅠ.ㅠ&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;또...분석 결과...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;Named Pipe에서 문제가 있었다... 내부에서 Thread가 도는데.. Pipe를 지속적으로 열었다 닫았다 하고 있었다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;난 여기서 Pipe를 한번만 열도록 수정을 했다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 젠장 Pipe가 Application으로부터 한번 수신을 받더니... 더이상 수신을 받지 않는 것이였다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;왜? 열었다 닫았다 했는지... 이해가 갔다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;다.. 생각이 있어서 그랬구나? 라는 생각이 머릿속을 스쳐갔다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;AmesianX&amp;nbsp;이 작성한 글에는 왜? Named Pipe를 사용했는지도 나와있었다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;일종의 게임 가드 같은 쉴드 프로그램으로부터 방해 받고 싶지 않다는 의도였다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다... 게임 매크로 같은것 만들때... 게임설치시 제공하는 가드가 DeviceIoControl API를 막아 버릴수 있다는 것이다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;내가 만드려는 용도는 게임 매크로 같은것이 아니라... 화상키보드 정도니까... 과감하게 Named Pipe를 드러냈다....&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 드라이버와 어플간의 통신하는 방법을 또 생각하고 연구를 했다....&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;디바이스를 어플과 연결할때..&amp;nbsp;&lt;/font&gt;AmesianX&amp;nbsp;소스에서는 GetFeature를 사용 해서 해당 디바이스를&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;찾는데 사용했다...거기에서 아이디어를 얻어서&amp;nbsp;SetFeature 로 어플에서 명령을 주면 되겠다고 생각했다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;예상은 적중했다. SetFeature로 통신 방식을 바꿨다.... 우선 아주 잘되었다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헌데 문제점이 하나 생겼다....&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DirectX 기반의 프로그램에서는 키보드 제어가 안먹힌다는것이다....&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이래 저래 웹서핑도 하고 또 여러 사람에게 물어본 결과.. DirectX는 키보드 떼는 속도를 아주 빠르게 해버리면.. 인식을 못한다고 한다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;내 생각에는 일종의 보안장치 같았다.. 사람이 뗄수 없는 속도로 키보드를 떼 버리면... 인식을 못한다고들 이야기 하더군..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그래서 어플에서 키보드 떼는 딜레이를 줄수 있도록 드라이버를 수정을 했다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 적중했다... 100ms 간격으로 키보드를 떼 주니까.. DirectX에서도 먹는것이었다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;이제 다 되었다 싶었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;누군가 블로그의 내 글을 보고... 싸게 넘기라고 했다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;(이하 고객이라 하겠음.)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;뭐 나름데로 노동의 댓가 만큼은 안받고... 싸게 넘겼다... 그 고객과 약속은 안했지만..&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;전화통화를 해보면서 판단했다 &amp;quot;훌륭한 버그 리포터일것 같다..&amp;quot; 라는 생각이 들었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;역시 그 고객은 훌륭한 버그 리포터 였다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;고객이 테스트 결과 장시간 마우스 키보드를 제어를 해 버리면.. CPU 부하가 이유없이 100% 먹으면서 컴퓨터 자체가 뻗어버리는 문제가 발생했다고 했다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 난 또 난관에 부딪혔다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;프로그래머 15년 차로서 이런 문제는 참 많이 다루었다... 힘들다기 보다는 이런 상황은 즐기는 단계까지 왔지 &amp;nbsp;ㅋㅋㅋ&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;저런 문제는 보통 메모리 릭 또는 동기화로 인해 발생을 한다... 거의 100% 이다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;짧은 시간에는 잘 돌다가 장시간 돌리면 죽는 프로그램 대부분이 그렇다는 것이다.....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;난 동기화와 메모리릭이 발생할만한 곳을 소스 분석했다... 그 결과 찾았다..&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;하나의 스택(함수) 안에서&amp;nbsp;IoCompleteRequest 요놈을 연속 두번 호출 하면 안된다는 것을 깨닭았다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;찾아낸 나도 대단하다.. 키보드 또는 마우스 값을 리셋하기 위해서 저놈을 하나의 스택에서 두번 처리해줬다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;결국은 동기화 문제였다.... 헌데... 내가 만든 프로그램은 키보드, 마우스 함께 되어 있는 형태라서...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;IoCompleteRequest 요놈을 한 스택(함수)에서 두번 호출하지 않으면 안되었다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;아!! 진짜 머리 터질듯 아팠다.... 프로그램은 팔아먹었지... 버그는 생겼지.. ㅋㅋㅋ&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그 순간 머릿속에 떠오른. 생각 &amp;quot;마우스 키보드를 같이 통합하지 말고.. 각각 떼어버리자..&amp;quot; 라는 생각..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;마우스 드라이버와 키보드 드라이버를 따로 떼어 버렸다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;어플에서는 마우스, 키보드 드라이버를 여는 파일핸들을 두개 만들었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐~~ 장시간 돌려도 된다.. ㅋㅋㅋ &amp;nbsp;가장 무식한 방법이 가장 현명한 방법이었던 것이다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;아!! 근데 고객의 또 &amp;nbsp;다른 질문... &amp;quot;마우스 상대좌표 방식은 가능하나요?&amp;quot; 라는 질문이었다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;내가 만든건 절대좌표 방식이었다....&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;나의 대답 &amp;quot;상대좌표에 관한 디스크립터만 있으면 가능할것 같습니다. &amp;quot; 라는 대답을 했다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;고객께서 상대좌표에 관한 디스크립터를 구해서 파일로 날려주셨다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헐.. 그거 적용하니까. 상대좌표가 인식이 되었다...&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그러다 누군가에게 &amp;quot;휠 기능은 안되요?&amp;quot; &amp;nbsp;라는 질문을 받았다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;이것 역시 디스크립터 였다. 디스크립터에 휠 기능을 활성화 해주고 어플의 통신 프로그램을 약간 고치니까.... 휠이 제어가 되었다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;고객께 휠 제어에 관한 부분까지 업데이트를 했다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;이제 거의 완성도가 높아졌다... 헐~~~&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;나의 데모버젼을 시연해 보신 분들이 많은 질문을 해왔다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;질문을 할때마다.. &amp;#39;아직 버그가 좀 있긴 하구나..&amp;#39; 라는 생각이 들었다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;그것을 토대로 계속 버그를 고쳐나가고 있는 중이다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;지금껏 개발했던 소스들을 정리를 해서 &amp;nbsp;기존에 DDK에서 제공했던 vhidmini 소스와 비교를 해봤다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;난 엄청 많은 코딩을 했다고 생각했는데.. 기존 vhidmini 소스와 별반 다를게 없고.. 약간 고쳐졌을 뿐..&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;ㅋㅋㅋㅋ 그래도 코드를 이해하고 찾는데 엄청 시간은 오래 걸렸다.. 한달 남짓? 준비 기간 까지 합치면.. 두달정도는 걸린것 같다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;지금은 완성도가 꽤 높아진 상태이다....&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;원래 만드려는 목적이 화상키보드 정도 만드려고 했고 DeviceIoControl API를 사용했으므로..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;게임 매크로 만드는데는 적합하지가 않을것 같다... 왜냐? 일부 가드에서는 DeviceIoControl API를&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;원천적으로 막는 것도 있다한다...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;헌데 고객께서는 온라인 게임 &amp;quot;로한&amp;quot; 에서는 잘 먹힌다고 했다..&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;되는것도 있고 안되는 것도 있을것이다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;고객께는 소스까지 죄다 제공을 했는데.. 이제 완성도가 높아진 지금은...&amp;nbsp;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;소스 공개는 절대 하지 않겠다.. 필요한 사람에게 dll과 드라이버 파일만을 거래 하겠다....&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face=&quot;Gulim, Arial&quot;&gt;(솔직히 위에도 말했지만 vhidmini 소스 조금만 고치면 되는거다.. 고치는 량은 얼마 안되도 고칠 부분을 찾는다는 것은 정말 힘들것이다..디바이스 드라이버를 전문적으로 해본 사람은 식은죽 먹기겠지만.)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;문의:&amp;nbsp;&lt;a href=&quot;mailto:bhcastle@naver.com&quot; target=&quot;_blank&quot;&gt;bhcastle@naver.com&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;가격은 키보드 드라이버 30만원, 마우스 드라이버 30만원&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;키보드 &amp;amp; 마우스 함께 구입시 50만원 입니다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 소스는 절대 거래하지 않는다는게 원칙이지만...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;굳이 구매를 하고 싶으시다면... 별도로 문의 바랍니다...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;[출처]&lt;/strong&gt;&amp;nbsp;&lt;a href=&quot;http://blog.naver.com/bhcastle/80158742701&quot; target=&quot;_blank&quot;&gt;가상키보드 마우스를 제작 후기..&amp;nbsp;&lt;/a&gt;|&lt;strong&gt;작성자&lt;/strong&gt;&amp;nbsp;&lt;a href=&quot;http://blog.naver.com/bhcastle&quot; target=&quot;_blank&quot;&gt;유리성&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/441228</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/441228#comment</comments>			<pubDate>Sun, 14 Feb 2016 10:24:05 +0900</pubDate>
		</item><item>
			<title>Virtual HID Mouse Driver 연구(펌)</title>
			<link>https://autolabs.co.kr/board_cFDS08/441204</link>
				<description>&lt;p&gt;본 문서는 파워해커에서 제작되었으며 무단배포를 허용함..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual HID Mouse Driver 연구&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;저자: AmesianX&lt;/p&gt; &lt;p&gt;제작: powerhacker.net&lt;/p&gt; &lt;p&gt;제작년도: 2009년 1월 15일&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[서문]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;본 문서의 시작에 앞서 목적에 대해 언급한다. 이 문서는 두가지 목적을 위해서 작성되어졌다.&lt;/p&gt; &lt;p&gt;첫번째는 모르는 부분에대한 새로운 연구나 공부를 시도할때 참고할 수 있는 공부방식(Style)에 대한 설명이고, 두번째는 Virtual HID Mouse Driver 를 제작할때 참고해야할 전초를 다지기위한 목적으로 구성되어 있다. 이렇게 기술문서를 공개하는 이유에는 여러가지가 있지만 무엇보다 이 기술이라는 분야는 언젠가는 자신이 알고있는 오늘의 기술이 내일의 쓰레기가 된다. 일찌감치 알고있는 정보들은 공개하고 더 높은 곳으로 계속 뛰어오를때 진정으로 아무도 가보지못한 고지에 오른 것이다. 그래야 스스로가 발전하는 길이고 바로 모두가 발전하는 길일 것이다. 고지는 점령 당하라고 있는 것이다. 언제까지 정적인 비공개노선으로 점령당하길 기다리고 있을 것인가? 앞으로는 더욱더 가속화될 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[기술을 습득하는 공부방법]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 새로운 기술을 알고싶다면 최대한 동일기능이 구현된 많은 소스들을 수집하라. 그리고 그 차이점을 소스분석을 통해서 캣치하라. 아마 대부분은 소스분석을 깊게 들어가지 않아도 차이점이 눈에 띄게 될 것이다. 그러나.. 아쉽게도 Virtual HID Mouse 에 대한 소스는 인터넷에서 거의 찾기 힘들 것이다. 물론, 공식적인 샘플들을 찾아낼 수 있지만 필자처럼 커널지식보다 유저레벨 어플리케이션 조작만 파온 사람은 그 유명업체들의 공식샘플을 보고도 감을 잡아내기는 하늘에 별따기처럼 어렵다. 즉, 프로그래밍 = 개념 이라는 공식이 있기 때문에 이 개념만 잡고나면 프로그래밍은 껌씹기나 마찬가지다. 개념을 잡는 요령이 있다면 그것은 바로 앞에서 언급한 동일기능 소스의 차이점을 분석해내는 것이다. 그렇기 때문에 매우 제한된 소스(공식소스들)를 갖고 시작하는 것은 전혀 이해를 이끌어내지 못한다. 최대한 고갈되었다고 생각될 정도로 많은 설명이나 소스들을 검색해서 찾아내야 한다. 이때 사용할 수 있는 방법은 구해낸 소스들의 일부 시그너처(Signature)를 검색키워드로 사용하는 것이다. 이런식으로 최대한 많은 정보들을 뽑다보면 선구자들의 질문들을 찾아낼 수 있다. 바로, 그 질문들에서 핵심개념들을 뽑아낼 수 있다. 자주 언급되는 사항이 바로 그 핵심일 것이다. 어떻게보면 &amp;quot;미네르바&amp;quot; 인지 &amp;quot;미네로하이바&amp;quot; 인지 그 친구처럼 철저한 검색기술로 무장한 채로 짜집기의 달인이 되어야만 할 필요가 있다. 만약 충분히 많이 찾아서 더이상 찾아낼 것 조차 없다고 느끼고 등골이 휘어지는 고통을 여러번 견뎌내었다면 이제 얻어낸 것들을 대상으로 비교분석을 취한다. 그렇게 되면 중요 키포인트가 눈에 보이게 될 것이다. 왜 이렇게 해야 하냐면 답은 간단하다. 스스로 엄청난 고통을 감뇌하면서 충분히 검색을 했는데 다 내용이 거기서 거기인 경우가 99.9% 일 것이다. 왜? 그것은 삽질하는 프로그래머가 택한 프로그래밍 방법론은 달라도 전체적인 흐름은 재밌게도 한가지밖에 없으니까. 이게 답이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;어라? 다 똑같은 소리만 짓거리고 있잖아? 뭔가 좀 더 구체적인 것을 달라고!!&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 소리가 나올때 이미 정답은 구해진 것이나 마찬가지다. 다 똑같은 소리를 짓거린다거나 똑같은 소스에 차이점은 있지만 원하는 것이 아니라고 생각될때 사실상 그것이 원하는 것일 확률이 태반이다. 그 이상의 짜집기(Copy &amp;amp; Paste) 능력은 밥을 숫갈로 퍼서 먹는 것이다. 그런데 필자같은 사람은 퍼서 먹여주는 것을 원한다. 왜? 프로그래밍이 나온 이유가 무엇인가? 로보트를 만들려고 기를 쓰는거보면 모르겠는가? 인간에게 숫갈로 밥을 퍼먹여 주려는게 궁극적인 목적아닌가? 프로그래머는 인간이 아니었나? (하기사 혹자는 로보트&lt;/p&gt; &lt;p&gt;라고도 부릅디다..) 프로그래머는 좀 퍼서 먹여주면 어디가 덧나는가? 짜증나게 약올리는 시스템 프로그래머들이여 퍼먹여주지 않으면 스스로 밥숫갈 놓게되는 날이 온다. 인터넷시대에서 정보라는 것은 물 흐르듯 흐를수 밖에 없기 때문에 빨리 털고 높은 곳으로 뛰지않으면 숫가락 놓을 준비를 해야 할 것이다. 오늘의 신기술이 내일의 쓰레기가 되는 시대에서 서로 돕지않으면 혼자 살아남기 힘들다. 외국애들 보라 오픈소스로 자기의 기술을 다 까발리고 있으면서도 항상 최첨단 기술을 걷고 있는 것을 보면 우리가 얼마나 어리석은지 진정 모르냐 이말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;외국애들은 오픈소스를 통해서 시너지라는 것을 이용하고 있다. 물론, 수 많은 개발자들이 다 참가해서 오픈소스가 완성될 것이라고 착각하면 그건 열라 바보이다. 유명 보안 오픈소스인 Nessus 개발자의 고충이 섞인 글을 읽어보았는가? 오픈소스임에도 불구하고 자기혼자만 개발해 왔다고 써있었다. 대부분의 오픈소스들이 마찬가지라고 보면 될 것이다. 다만, 시너지효과로 인해 개발자 1명이 해낼수 있는 능력이 100명 1000명 수준으로 증폭되었기에 프로젝트가 맥을 이어갈 수 있는 것이다. 즉, 게임용어로 말하면 &amp;quot;버프&amp;quot;(버프를 모르진 않겠지..) 를 받은 것이다. 그렇게 되면 소수의 엘리트 파워가 오픈소스에 집중되는 일반유저의 관심만큼 증폭되기 때문이다. 단순히 눈에보이는게 전부라고 생각한다면 큰 것을 놓치게된다. (아니라고? 아님말고.. 허위사실 유포로 감금되어야 하나.. ㅎㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[현 상황]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현 상황에서는 Virtual HID Mouse 가 Auto Mouse 나 MACRO 라는 시장에서 대안으로 대두된 상태라 x시장에서도 드라이버의 판매가 이루어지고 있는 상황이다. 참고로 이 기술이나 드라이버를 판매자체는 사실 법적인 문제의 소지가 없다. 왜냐면 이 Virtual HID Mouse 기술은 범용기술이기 때문이다. 이 기술이 사용되고있는 쪽은 예를들면 조이스틱을 에뮬레이션하거나(용산에가면 조이스틱 판다..) 블루투스 마우스를 사용하도록 해주거나 혹은 그에 버금가는 마우스 업체들이 주로 보유하고있는 자체기술에서 많이 볼 수 있다. 이건 우리가 늘상 접하는 일반분야에서 말한것 뿐이고 무엇보다 가장 많이 사용되고 있는 곳은 임베디드 산업에서일 것이다. 그러므로 이 기술을 파는 것은 전혀 문제가 될 수 없다. 이 기술자체는 Microsoft 사에서 공식적으로 WinDDK 에 예제와 함께 배포하고 있다는 사실을 알만한 사람들은 이미 다 알고있겠다. 단지 그 이상의 자세한 정보를 찾기가 어렵고 Microsoft 사에서 제공하는 기술정보를 알기위해서 밑받침(선행) 되어야할 정보가 없다는 것이 문제점이다. 그래서 기존에 커널 드라이버를 개발하던 사람들이나 천국이지 필자같은 미천한 어플프로그래머들한테는 짜증만 나게 할 뿐이다. 이 중간에 생략된 정보들이 무엇인지 알아내야 한다. 그것이 유저레벨이라는 미천한 신분에서 커널레벨이라는 귀족신분으로 도약할 수 있는 길이다. 테스트환경 만드는게 짜증나서 공부하지 않았다가 완전 독박 쓴 기분이기에 좀 고약한 말투가 나온다. (기분 상하는 커널레벨의 고급 독자는 당장 이 문서를 접기 바란다. 필자도 커널레벨을 공부해야 윈도우를 진정으로 아는 것이라는 대에 이견이 없다. 다만, 오래전부터 블루스크린과 친구를 맺고싶지 않았을 뿐이다. 이거 참.. 뻘쭘하게 커널과 &amp;quot;절친노트&amp;quot; 라도 찍어야하나..)&lt;/p&gt; &lt;p&gt;===================================================================================================================&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현재, 인터넷에는 몇몇의 기술 정보이외에는 관련된 기술적 자료를 찾아볼 수 없다고 해도 과언이 아니다. 진짜 짜증나도록 자료가 없다. 이해를 할 수 있을만한 한글로된 기술자료는 극적으로 한개를 찾을 수 있었다. 먼저, Virtual HID Mouse 를 찾아보면 가장먼저 접하게 되는 사이트가 있다. 까마귀라는 한국사람이 자신이 만들었다고하는 Virtual HID Mouse 가 검색이 된다. 블로그의 글 내용인데 사실 저수준을 다루는 고급개발자가 아니면 볼게없다.. (왜? 필자같은 어플프로그래밍 수준은 못알아 먹으니까.. + 안갈켜주니까&lt;/p&gt; &lt;p&gt;-_-;) 그리고 MSDN 이 검색되고 vhidmini 라는 것이 검색된다. 또한, 짱개 사이트의 vhidmouse 라는 소스와 hidmouse 라는 소스도 검색된다. 근데.. 오래전에 GxxxGuard 라는 소스가 인터넷에 떴다는 그 몹쓸 짱개사이트였다. 구현을 하기 위해서는 vhidmini 라는 소스가 그중에서 제일 유력한 후보가 될 것이고 나머지 vhidmouse 와 hidmouse 는 소스를 구하는데 한참이나 걸릴 것이다. 일단, 대충 둘러서 정보를 캣치해야한다. 다음은 이미 다들 알고있겠지만 SoftICE 라는 걸작을 만들어낸 &amp;quot;Numega Soft&amp;quot; 라는 회사의 Virtual HID Mouse 공식샘플의 일부소스이다. 아쉽게도 이 소스는 Windows 9x 계열에서 작동되는 드라이버이므로 NT 계열에서는 사용할 수 없다. 하지만 캣치할 수 있는 중요한 내용이 포함되어 있다. 위에서 언급한 것중에 vhidmouse 라는 것이다. 다음은 vhidmouse 소스 중의 일부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// vmoudev.cpp - &amp;nbsp;virtual mouse device for HID example &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Compuware Corporation &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// NuMega Lab &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// 9 Townsend West &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Nashua, NH 03060 &amp;nbsp;USA &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Copyright (c) 1998 Compuware Corporation. All Rights Reserved. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Unpublished - rights reserved under the Copyright laws of the &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// United States. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// This module implements the device class of the virtual HID &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// mouse minidriver. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;lt;KHID.H&amp;gt; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;vmoudev.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;hidmouse.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;KTrace T(&amp;quot;&amp;quot;,TRACE_MONITOR, TraceAlways, BreakNever, KUstring(L&amp;quot;HidMouse&amp;quot;)); &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEX 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEY 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, // Logical Maximum (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, // Report Count (3), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, // Report Size (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, // Input (Data, Variable, Absolute), &amp;nbsp; &amp;nbsp;;3 button bits &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, // Report Count (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, // Report Size (5), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, // Input (Constant), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, // Usage (X), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, // Usage (Y), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, // Logical Minimum (-127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, // Logical Maximum (127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, // Report Size (8), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, // Report Count (2), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, // Input (Data, Variable, Relative), &amp;nbsp; &amp;nbsp;;2 position bytes (X &amp;amp; Y) &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; // End Collection, &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// End Collection &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// HardwareID for the virtual mouse. &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR HardwareID[]={L&amp;quot;ROOT\NUMEGA_VIRTUAL_HID_MOUSE&lt;/p&gt; &lt;p&gt;본 문서는 파워해커에서 제작되었으며 무단배포를 허용함..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual HID Mouse Driver 연구&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;저자: AmesianX&lt;/p&gt; &lt;p&gt;제작: powerhacker.net&lt;/p&gt; &lt;p&gt;제작년도: 2009년 1월 15일&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[서문]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;본 문서의 시작에 앞서 목적에 대해 언급한다. 이 문서는 두가지 목적을 위해서 작성되어졌다.&lt;/p&gt; &lt;p&gt;첫번째는 모르는 부분에대한 새로운 연구나 공부를 시도할때 참고할 수 있는 공부방식(Style)에 대한 설명이고, 두번째는 Virtual HID Mouse Driver 를 제작할때 참고해야할 전초를 다지기위한 목적으로 구성되어 있다. 이렇게 기술문서를 공개하는 이유에는 여러가지가 있지만 무엇보다 이 기술이라는 분야는 언젠가는 자신이 알고있는 오늘의 기술이 내일의 쓰레기가 된다. 일찌감치 알고있는 정보들은 공개하고 더 높은 곳으로 계속 뛰어오를때 진정으로 아무도 가보지못한 고지에 오른 것이다. 그래야 스스로가 발전하는 길이고 바로 모두가 발전하는 길일 것이다. 고지는 점령 당하라고 있는 것이다. 언제까지 정적인 비공개노선으로 점령당하길 기다리고 있을 것인가? 앞으로는 더욱더 가속화될 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[기술을 습득하는 공부방법]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 새로운 기술을 알고싶다면 최대한 동일기능이 구현된 많은 소스들을 수집하라. 그리고 그 차이점을 소스분석을 통해서 캣치하라. 아마 대부분은 소스분석을 깊게 들어가지 않아도 차이점이 눈에 띄게 될 것이다. 그러나.. 아쉽게도 Virtual HID Mouse 에 대한 소스는 인터넷에서 거의 찾기 힘들 것이다. 물론, 공식적인 샘플들을 찾아낼 수 있지만 필자처럼 커널지식보다 유저레벨 어플리케이션 조작만 파온 사람은 그 유명업체들의 공식샘플을 보고도 감을 잡아내기는 하늘에 별따기처럼 어렵다. 즉, 프로그래밍 = 개념 이라는 공식이 있기 때문에 이 개념만 잡고나면 프로그래밍은 껌씹기나 마찬가지다. 개념을 잡는 요령이 있다면 그것은 바로 앞에서 언급한 동일기능 소스의 차이점을 분석해내는 것이다. 그렇기 때문에 매우 제한된 소스(공식소스들)를 갖고 시작하는 것은 전혀 이해를 이끌어내지 못한다. 최대한 고갈되었다고 생각될 정도로 많은 설명이나 소스들을 검색해서 찾아내야 한다. 이때 사용할 수 있는 방법은 구해낸 소스들의 일부 시그너처(Signature)를 검색키워드로 사용하는 것이다. 이런식으로 최대한 많은 정보들을 뽑다보면 선구자들의 질문들을 찾아낼 수 있다. 바로, 그 질문들에서 핵심개념들을 뽑아낼 수 있다. 자주 언급되는 사항이 바로 그 핵심일 것이다. 어떻게보면 &amp;quot;미네르바&amp;quot; 인지 &amp;quot;미네로하이바&amp;quot; 인지 그 친구처럼 철저한 검색기술로 무장한 채로 짜집기의 달인이 되어야만 할 필요가 있다. 만약 충분히 많이 찾아서 더이상 찾아낼 것 조차 없다고 느끼고 등골이 휘어지는 고통을 여러번 견뎌내었다면 이제 얻어낸 것들을 대상으로 비교분석을 취한다. 그렇게 되면 중요 키포인트가 눈에 보이게 될 것이다. 왜 이렇게 해야 하냐면 답은 간단하다. 스스로 엄청난 고통을 감뇌하면서 충분히 검색을 했는데 다 내용이 거기서 거기인 경우가 99.9% 일 것이다. 왜? 그것은 삽질하는 프로그래머가 택한 프로그래밍 방법론은 달라도 전체적인 흐름은 재밌게도 한가지밖에 없으니까. 이게 답이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;어라? 다 똑같은 소리만 짓거리고 있잖아? 뭔가 좀 더 구체적인 것을 달라고!!&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 소리가 나올때 이미 정답은 구해진 것이나 마찬가지다. 다 똑같은 소리를 짓거린다거나 똑같은 소스에 차이점은 있지만 원하는 것이 아니라고 생각될때 사실상 그것이 원하는 것일 확률이 태반이다. 그 이상의 짜집기(Copy &amp;amp; Paste) 능력은 밥을 숫갈로 퍼서 먹는 것이다. 그런데 필자같은 사람은 퍼서 먹여주는 것을 원한다. 왜? 프로그래밍이 나온 이유가 무엇인가? 로보트를 만들려고 기를 쓰는거보면 모르겠는가? 인간에게 숫갈로 밥을 퍼먹여 주려는게 궁극적인 목적아닌가? 프로그래머는 인간이 아니었나? (하기사 혹자는 로보트&lt;/p&gt; &lt;p&gt;라고도 부릅디다..) 프로그래머는 좀 퍼서 먹여주면 어디가 덧나는가? 짜증나게 약올리는 시스템 프로그래머들이여 퍼먹여주지 않으면 스스로 밥숫갈 놓게되는 날이 온다. 인터넷시대에서 정보라는 것은 물 흐르듯 흐를수 밖에 없기 때문에 빨리 털고 높은 곳으로 뛰지않으면 숫가락 놓을 준비를 해야 할 것이다. 오늘의 신기술이 내일의 쓰레기가 되는 시대에서 서로 돕지않으면 혼자 살아남기 힘들다. 외국애들 보라 오픈소스로 자기의 기술을 다 까발리고 있으면서도 항상 최첨단 기술을 걷고 있는 것을 보면 우리가 얼마나 어리석은지 진정 모르냐 이말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;외국애들은 오픈소스를 통해서 시너지라는 것을 이용하고 있다. 물론, 수 많은 개발자들이 다 참가해서 오픈소스가 완성될 것이라고 착각하면 그건 열라 바보이다. 유명 보안 오픈소스인 Nessus 개발자의 고충이 섞인 글을 읽어보았는가? 오픈소스임에도 불구하고 자기혼자만 개발해 왔다고 써있었다. 대부분의 오픈소스들이 마찬가지라고 보면 될 것이다. 다만, 시너지효과로 인해 개발자 1명이 해낼수 있는 능력이 100명 1000명 수준으로 증폭되었기에 프로젝트가 맥을 이어갈 수 있는 것이다. 즉, 게임용어로 말하면 &amp;quot;버프&amp;quot;(버프를 모르진 않겠지..) 를 받은 것이다. 그렇게 되면 소수의 엘리트 파워가 오픈소스에 집중되는 일반유저의 관심만큼 증폭되기 때문이다. 단순히 눈에보이는게 전부라고 생각한다면 큰 것을 놓치게된다. (아니라고? 아님말고.. 허위사실 유포로 감금되어야 하나.. ㅎㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[현 상황]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현 상황에서는 Virtual HID Mouse 가 Auto Mouse 나 MACRO 라는 시장에서 대안으로 대두된 상태라 x시장에서도 드라이버의 판매가 이루어지고 있는 상황이다. 참고로 이 기술이나 드라이버를 판매자체는 사실 법적인 문제의 소지가 없다. 왜냐면 이 Virtual HID Mouse 기술은 범용기술이기 때문이다. 이 기술이 사용되고있는 쪽은 예를들면 조이스틱을 에뮬레이션하거나(용산에가면 조이스틱 판다..) 블루투스 마우스를 사용하도록 해주거나 혹은 그에 버금가는 마우스 업체들이 주로 보유하고있는 자체기술에서 많이 볼 수 있다. 이건 우리가 늘상 접하는 일반분야에서 말한것 뿐이고 무엇보다 가장 많이 사용되고 있는 곳은 임베디드 산업에서일 것이다. 그러므로 이 기술을 파는 것은 전혀 문제가 될 수 없다. 이 기술자체는 Microsoft 사에서 공식적으로 WinDDK 에 예제와 함께 배포하고 있다는 사실을 알만한 사람들은 이미 다 알고있겠다. 단지 그 이상의 자세한 정보를 찾기가 어렵고 Microsoft 사에서 제공하는 기술정보를 알기위해서 밑받침(선행) 되어야할 정보가 없다는 것이 문제점이다. 그래서 기존에 커널 드라이버를 개발하던 사람들이나 천국이지 필자같은 미천한 어플프로그래머들한테는 짜증만 나게 할 뿐이다. 이 중간에 생략된 정보들이 무엇인지 알아내야 한다. 그것이 유저레벨이라는 미천한 신분에서 커널레벨이라는 귀족신분으로 도약할 수 있는 길이다. 테스트환경 만드는게 짜증나서 공부하지 않았다가 완전 독박 쓴 기분이기에 좀 고약한 말투가 나온다. (기분 상하는 커널레벨의 고급 독자는 당장 이 문서를 접기 바란다. 필자도 커널레벨을 공부해야 윈도우를 진정으로 아는 것이라는 대에 이견이 없다. 다만, 오래전부터 블루스크린과 친구를 맺고싶지 않았을 뿐이다. 이거 참.. 뻘쭘하게 커널과 &amp;quot;절친노트&amp;quot; 라도 찍어야하나..)&lt;/p&gt; &lt;p&gt;===================================================================================================================&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현재, 인터넷에는 몇몇의 기술 정보이외에는 관련된 기술적 자료를 찾아볼 수 없다고 해도 과언이 아니다. 진짜 짜증나도록 자료가 없다. 이해를 할 수 있을만한 한글로된 기술자료는 극적으로 한개를 찾을 수 있었다. 먼저, Virtual HID Mouse 를 찾아보면 가장먼저 접하게 되는 사이트가 있다. 까마귀라는 한국사람이 자신이 만들었다고하는 Virtual HID Mouse 가 검색이 된다. 블로그의 글 내용인데 사실 저수준을 다루는 고급개발자가 아니면 볼게없다.. (왜? 필자같은 어플프로그래밍 수준은 못알아 먹으니까.. + 안갈켜주니까&lt;/p&gt; &lt;p&gt;-_-;) 그리고 MSDN 이 검색되고 vhidmini 라는 것이 검색된다. 또한, 짱개 사이트의 vhidmouse 라는 소스와 hidmouse 라는 소스도 검색된다. 근데.. 오래전에 GxxxGuard 라는 소스가 인터넷에 떴다는 그 몹쓸 짱개사이트였다. 구현을 하기 위해서는 vhidmini 라는 소스가 그중에서 제일 유력한 후보가 될 것이고 나머지 vhidmouse 와 hidmouse 는 소스를 구하는데 한참이나 걸릴 것이다. 일단, 대충 둘러서 정보를 캣치해야한다. 다음은 이미 다들 알고있겠지만 SoftICE 라는 걸작을 만들어낸 &amp;quot;Numega Soft&amp;quot; 라는 회사의 Virtual HID Mouse 공식샘플의 일부소스이다. 아쉽게도 이 소스는 Windows 9x 계열에서 작동되는 드라이버이므로 NT 계열에서는 사용할 수 없다. 하지만 캣치할 수 있는 중요한 내용이 포함되어 있다. 위에서 언급한 것중에 vhidmouse 라는 것이다. 다음은 vhidmouse 소스 중의 일부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// vmoudev.cpp - &amp;nbsp;virtual mouse device for HID example &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Compuware Corporation &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// NuMega Lab &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// 9 Townsend West &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Nashua, NH 03060 &amp;nbsp;USA &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Copyright (c) 1998 Compuware Corporation. All Rights Reserved. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Unpublished - rights reserved under the Copyright laws of the &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// United States. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// This module implements the device class of the virtual HID &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// mouse minidriver. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;lt;KHID.H&amp;gt; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;vmoudev.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;hidmouse.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;KTrace T(&amp;quot;&amp;quot;,TRACE_MONITOR, TraceAlways, BreakNever, KUstring(L&amp;quot;HidMouse&amp;quot;)); &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEX 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEY 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, // Logical Maximum (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, // Report Count (3), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, // Report Size (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, // Input (Data, Variable, Absolute), &amp;nbsp; &amp;nbsp;;3 button bits &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, // Report Count (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, // Report Size (5), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, // Input (Constant), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, // Usage (X), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, // Usage (Y), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, // Logical Minimum (-127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, // Logical Maximum (127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, // Report Size (8), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, // Report Count (2), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, // Input (Data, Variable, Relative), &amp;nbsp; &amp;nbsp;;2 position bytes (X &amp;amp; Y) &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; // End Collection, &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// End Collection &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// HardwareID for the virtual mouse. &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR HardwareID[]={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR DeviceID[] &amp;nbsp;={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_DEVICE_ATTRIBUTES DeviceAttributes = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; sizeof(HID_DEVICE_ATTRIBUTES), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VENDOR_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PRODUCT_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; VERSION_NUMBER &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; };&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같이 HID_REPORT_DEscRIPTOR 라는 것을 볼 수 있는데, 처음에는 이게 뭔지 모른다. 감도 안온다. 그러므로 그 관점을 그대로 두고 다음으로 넘어가서 다른 소스들을 보자. (처음엔 원래 모르겠지.. 나만그런가.. -_-; 제길..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;인터넷에서 검색하면 위의 소스와 MSDN (Microsoft 사의 공식샘플과 설명문서) 을 먼저 보게 될 것이다. 그러면 당연히 vhidmini 라는 것도 접하게 된다. 소스는 인터넷에서 파는 놈들도 있으니 그냥 찾기는 좀 짜증이 날 것이다. Microsoft 사의 홈페이지에서 WinDDK 를 받으라. 그 안에 VHidMini 라는 샘플이 들어있다. 그놈을 보면 다음과 같이 생겨먹은 부분에 주목하자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (NT_SUCCESS(ntStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Use default &amp;quot;HID Descriptor&amp;quot; (hardcoded). We will set the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // wReportLength memeber of HID descriptor when we read the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // the report descriptor either from registry or the hard-coded&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // one.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Microsoft 에서 MSDN 의 설명을 먼저 읽어본 뒤 위의 소스주석부분을 보자. 다음과 같이 친절하게 설명해주고 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;설명에 써있듯이 자기네는 그냥 하드코딩 했으니까 ReadFromRegistry 를 참고하면 다른 디바이스를 등록할 수 있단다. 처음 접할땐 사전지식이 없기에 &amp;quot;이게 뭔 개소리야?&amp;quot; 라고 생각이 들 것이다. (? 반응이 없으면 나만그런거 같다.. ㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다면 이제 개소리는 집어치우고 다음을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--&amp;gt; &amp;nbsp;https://www.osronline.com/showthread.cfm?link=138652&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Radly&lt;/p&gt; &lt;p&gt;xxxxxx@daryllee.com&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This being my first driver project, and an unusual one at that, there&amp;#39;s a lot to get my&lt;/p&gt; &lt;p&gt;head wrapped around. My intent is to produce a virtual HID device (mouse emulation) that&lt;/p&gt; &lt;p&gt;uses a complex non-HID physical device as the input medium. I&amp;#39;m using the VHidMini sample&lt;/p&gt; &lt;p&gt;from the WDK hid folder as a starting point, and I&amp;#39;m now at the point where I need to transform&lt;/p&gt; &lt;p&gt;the sample&amp;#39;s report format into a mouse format. I notice with confusion that the report descriptor&lt;/p&gt; &lt;p&gt;in vhidmini.inf is different from that in vhidmini.h, with no explanation in vhidmini.htm as&lt;/p&gt; &lt;p&gt;to why they are different. Does anyone here have any insight on that?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 놈이 필자가 생각하는 것과 동일한 구현을 해볼려고 삽질중에 무시무시한 고급개발자들과 해커들이 몰린다는 osronline 에 질문을 던져놓고 있다. 이 소리는 무엇인가? 필자도 결국 저 문제에 봉착하게 될 날이 온다는 시나리오를 미리 발견한 것이다. 그러므로 주의 깊게 읽어볼 필요가 있다. 여기서 얻어낼 수 있는 정보는 sample&amp;#39;s report format 이란 것과 report descriptor 라는 두가지 내용이다. 원래부터 찾기힘든 정보들에는 동문서답 내지는 &amp;quot;내가 니 밥처먹는데 밥숫가락으로 퍼먹여주랴?&amp;quot; 정도의 댓글이 달리는데 그래도 이 글의 답글중에 괜찮은 답글이 있다. 근데.. 여전히 찾기힘든 정보만큼이나 짤막하게 달아놓는다. 이런사람이 있다는 것은 희망이고 곧 빛이다. 다음의 답글을 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;입에서 욕은 나온다. 왜? 말할라면 다 말하던가 아니면 동문서답이나 하고 가던가 감칠맛나게 소스 네줄 뿌리고 튀다니.. 그래도 고맙다. 지식을 갈구하는 자에게는 이것조차 선물이다. 제길.. 현자라면 푸념할때가 아닌거 같다. 여기서 뭔가 개념을 잡을 수 있는 정보를 캣치해야만 한다. 이 글에서 외국아가(짱개류 외국애인지 allen zhang 이구나.. 역시 중국은 AUTO 에 강한가보다..) 말하기를 소스코드를 보란다. 그 안에 ReadDescriptorFromRegistry 를 보라고 권하면서 일부 소스를 긁어서 보여준다. 글은 짧지만 분명 소스를 열어봤기에 긁어서 붙여줬을테니 아쉬워도 고마운 행동이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 보라고 한 소스가 바로 위에서 VHidMini 샘플의 일부분이라고 뿌린 부분이다. 즉, 이 부분의 내용은 최초 질문자의 글에서 캣치한 sample&amp;#39;s report format 와 report descriptor 라는 부분에대한 응답이다. 즉, 이 함수의 이름으로부터 알 수 있듯이 레지스트리로부터 디스크립터를 읽어들인다는 것에 바로 Virtual HID Mouse 의 핵심구현이 얽혀있다는 것을 시사한다는 점을 알 수 있다. 그런데 필자도 단지 이두개만 가지고 감을 잡지는 못했다. 왜냐면, 커널을 깊이 공부한 적이 없는 사람이 이 두가지의 자료만을 토대로 감을 잡아낼 수 있겠는가? 그렇다면 그건 천재이거나 영어를 모국어처럼 잘하는 사람일게 분명하다. 필자는 남보다 항상 두배로 삽질을 하는데 머리가 남들보다 딸려서 그렇다. 자료도 항상 두배로 찾아야 한다. 결정적으로 힌트가 되었던 것은 역시 국내사이트인데 드라이버 개발정보를 알려주는 곳인 driveronline.org 에서의 힌트와 임베디드 계통의 KELP 사이트에서 였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://driveronline.org/bbs/view.asp?tb=beusb&amp;amp;GotoPage=1&amp;amp;s_bulu=memo&amp;amp;s_key=pnp&amp;amp;no=1491&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Re] Re] Re] USB 가상 키보드, 마우스 드라이버&lt;/p&gt; &lt;p&gt;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.10.02:10.40 (화)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; Woof&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 605&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;pnp 를 이용해서든지 해서 가상적인 usb 장치가 인식이 되면 일반적인 usb 장치를 다루듯이 이용하시면 됩니다. 일반적으로 실제 장치들은 &amp;nbsp;Windows에서 제공하는 기본적인 드라이버로도 동작하기 때문에 필요가 없지만 이와 같은 경우에는 간단하게 자기 드라이버를 열어서 인식된 장치 device와 통신하는 드라이버 정도는 필요하겠지요. 뭐, usb라서 따로 드라이버없이 application으로도 충분히 가능한건데 다들 위와 같은 방법을 이용하더군요. 새로나온 umdf 등을 이용하면 더 간단하고 새로나온 것에 대한 공부도 하면서 재미나게 할 수 있을지도 모르겠네요. 위 에서 말한 대부분의 경우 라고 한 것의 예를 간단히 들어보면 자신의 드라이버를 올리고 해당 드라이버에서 application과 통신 device를 생성한 뒤에 pnp를 이용해서 가상적인 usb 장치를 만들고 그것과 통신하는 길?을 적당히 만들어서 이용하시면 됩니다. sample에서는 가상적인 장치 인식이 바로 usb나 그런 부분이 아니였던 것 같은데 적당히 고치면 되겠지요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에도 썻지만, 잘 찾으면 다 만들어진 코드 어디 있을 것 같습니다. 저도 한번 찾으려다가 그냥 sample에 있어서 말았는데. :| &amp;nbsp;해당 usb 드라이버를 이용해서&amp;quot; 라는 부분에 대해서 물어보셔서 이 부분만 따로 답을 달면 해당 usb device를 제어(control)하는 드라이버를 지칭했습니다. &amp;nbsp;또 처음에 말한 것 처럼 class관련 드라이버에 대해서는 생각할 필요가 없습니다. 역시 위에 쓴 것 처럼 어디에 쓰실지 궁금하네요. 가상 키입력등은 S/W나 그런 자동화 테스트에 이용하기도 하고 꽤 여러군데서 쓰기는 하는데 안좋지는 않지만 뭐 . 그런데도 쓰여서 :|&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;최초 질문자가 어떻게 구현해야 하냐고 질문하자 pnp 를 통해서 가상적인 usb 를 인식시킨 다음에 적당히 device 와 통신시키라고 한다. 자세한 내용은 말해주지 않고 Microsoft 에서 제공하는 샘플로도 구현이 가능할 것이라는 내용과 어딘가에는 이미 다 만들어진 소스가 있을텐데 찾아보라고 한다. 이말 믿고 인터넷에서 찾아헤메다가는 마누라가 집나가도 모를것이다. 답변에서 보듯이 이 사람은 진짜 적당히 답글을 달고 있는 사람이라는 점을 주의해야 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 사람의 힌트와 통찰력이 Microsoft 사의 샘플에서 존재하는 핵심이라는 점을 알 수 있다. 일단, 정보는 머리속에 꼬깃꼬깃 담아두고 계속 다음 검색으로 넘어가면서 본인의 마음속에 답이 한가지로 수렴되도록 정보들을 계속 얻어 내어보자. 이쯤되면 정상적인 사이트를 뒤지는 것이 힘들어진다. 왜냐면 너무 정보가 부족하기 때문이리라. 고로 컨트롤러를 제어하는 것을 찾아본다. 예를들면 USB HID 조이스틱 드라이버 같은 것을 찾아내는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;다음과 같은 좋은 예가 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.redcl0ud.com/files/XBCD_all_src.cab&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBOX 의 6축 조이스틱 패드를 윈도우에서 사용할 수 있도록 해주는 소스였다. 검색을 할때는 기존에 얻었던 소스에서 일부 특이하게 보일만한 함수를 키워드로 검색하면 운좋게 찾을 수 있다. 소스를 보면 너무 길고 난해하고 이해하기 힘들뿐이다. 당연히 커널관련 지식이 깊지않은 이상 어떻게 분석하고싶어도 그럴 도리가 없다. 그러므로 파일구성을 보는 것이 전부이다. 여기서 또한가지 힌트를 얻을 수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBCD_control.c&lt;/p&gt; &lt;p&gt;XBCD_driver.c&lt;/p&gt; &lt;p&gt;XBCD_driver.h&lt;/p&gt; &lt;p&gt;XBCD_hid.h&lt;/p&gt; &lt;p&gt;XBCD_report.h&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 파일구성에서 driver 나 control 소스를 보기전에 report 라는 눈에 띄는 놈이 있다. 이 헤더파일의 내용을 보게되면 다음과 같은 것이 적혀있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x05, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 5)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x06, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 6)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 9)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0a, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 10)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0b, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 11)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0c, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 12)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Cnst,Ary,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x16, 0x01, 0x80, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (-32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (X)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Simulation Controls)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xba, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Rudder)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xbb, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Throttle)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x39, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Hat switch)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0x3b, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (315)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x65, 0x14, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; UNIT (Eng Rot:Angular Pos)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0d, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 13)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0e, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 14)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 15)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Not Defined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x91, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; OUTPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xc0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // END_COLLECTION&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 이 홈페이지에서 최대한 얻을 수 있는 것은 다 캣치해야 하는 http://www.redcl0ud.com/xbcd.html 홈페이지의 마지막쯤에 보면 http://www.redcl0ud.com/files/USBView.cab 라는 것이 있다. 그리고 캡춰사진이 있는데 핵심사항으로 체크를 해둔 부분이 있다. idVendor, idProduct 라는 부분에 체크를 해두고 있다. 그리고 USBView 에서 보여주는 내용이 모냐면 바로 Device Descriptor 였다. 오호라.. 내친김에 이 사이트에서는 USB 드라이버를 제작하는 방법까지 설명하는 링크를 걸어두고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://euc.jp/periphs/xbox-controller.en.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 링크인데 제목은 &amp;quot;Inside XBox Controller&amp;quot; 라고 되어있다. 대충 무슨내용이 있는지 열거하자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;lt;Inside Xbox Controller&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Overview&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;USB Device Model&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Descriptors&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here are descriptor dumps of the hub, the gamepad and the memory unit.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the integrated hub&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the gamepad (American)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the memory unit&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Vendor/Product IDs&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The vendor ID is 0x045e (Microsoft). Product IDs are as follows:&lt;/p&gt; &lt;p&gt;ID &amp;nbsp; &amp;nbsp;product&lt;/p&gt; &lt;p&gt;0x001c &amp;nbsp; &amp;nbsp;integrated hub&lt;/p&gt; &lt;p&gt;0x0202 &amp;nbsp; &amp;nbsp;gamepad (American)&lt;/p&gt; &lt;p&gt;0x0280 &amp;nbsp; &amp;nbsp;memory unit&lt;/p&gt; &lt;p&gt;0x0284 &amp;nbsp; &amp;nbsp;DVD remote receiver&lt;/p&gt; &lt;p&gt;0x0285 &amp;nbsp; &amp;nbsp;gamepad (Japanese)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;It is not recommended to distinguish Xbox gamepads by vendor/product IDs because third-party controllers may&lt;/p&gt; &lt;p&gt;have their own vendor/product IDs.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Device Class&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;HID Report Format&amp;gt;&lt;/p&gt; &lt;p&gt;Input Report&lt;/p&gt; &lt;p&gt;The input report is 20-byte.&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Output Report&lt;/p&gt; &lt;p&gt;The output report (rumble control) is 6-byte.&amp;nbsp;&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Example of HID Report Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;The Xbox gamepad lacks the HID report descriptor that describes the input/output report formats. Based on the&lt;/p&gt; &lt;p&gt;above report formats I have tried writing the report descriptor for your information. This is a mere example;&lt;/p&gt; &lt;p&gt;neither official nor verified. Accuracy is not guaranteed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Text format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Binary format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * HID Descriptor Tool format (to be loaded into HID Descriptor Tool)&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 내용들이 있었다. 상당히 많은 삘을 주고있다. 누가봐도 HID Descriptor 와 HID Report Format 그리고 Input Report 와 Output Report 를 통해서 통신한다는 아주 기본적인 컨셉(개념)은 머리가 아니라(T.T) 가슴에 와닿을 것이다. (젠쟝.. 가슴에만 담아두마.. -_-;) 일단, 이쯤에서 XBCD 소스는 닫아둔다. 언제 이거 분석하고 앉아있는가.. 최종컨셉이 다르기 때문에 힌트만 뽑아먹고 닫아두는 것이다. 애초에 만들려고 한건 Virtual HID Mouse 인데 이건 그 컨셉이 아니기에 대충 훑어보고 넘겨야 한다. 또 다른 소스들을 보자. 마구잡이로 검색하면서 받아둔 소스중에 앞에서 처음에 말했던 hidmouse 라는 소스를 한번 진단해보자.. -_-;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(PIC 를 이용한 마우스 제작소스)&lt;/p&gt; &lt;p&gt;파일을 열어보니 원하는게 아닌듯 보였는데 알고보니 PIC 용이었다. 운 좋게도 필자는 PIC18x 롬라이터를 갖고 있어서 이 소스가 뭔지 알 수 있었다. 오래전에 친구의 부탁으로 PIC18x 칩에 어셈블리를 롬라이팅 하는 프로그램을 만들어준 적이 있어서 무슨 소스인지 금방 알 수 있었다. 요새는 PIC 프로그래밍에도 C 가 쓰이고 PIC 는 PLC 대체용으로 쓰이기도 한다. 그런데 PIC 로 USB 모듈을 부착하고 마우스로 제작이 가능한거 같았다. 어쨌거나 원하는 내용은 아니었지만 생각해보면 가장 중요한 것이 물리적인 장치 아닌가? 물리적인 장치에서는 기존에 찾은 소스들이나 검색내용들과 어떤 차이가 있는지 알아볼 필요도 있다.&lt;/p&gt; &lt;p&gt;http://www.pudn.com/downloads128/sourcecode/comm/detail543439.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 라는 소스에서 파일구성을 보면 특이한 놈이 있다.&lt;/p&gt; &lt;p&gt;usb_descriptors.c 라는 소스가 있는데 여태까지 눈여겨왔던 descriptor 라는 단어가 보일 수 밖에 없다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;/* Device Descriptor */&lt;/p&gt; &lt;p&gt;ROM USB_DEVICE_DEscRIPTOR device_dsc=&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x12, &amp;nbsp; &amp;nbsp;// Size of this descriptor in bytes&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_DEscRIPTOR_DEVICE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// DEVICE descriptor type&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0200, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USB Spec Release Number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Class Code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Subclass code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Protocol code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_EP0_BUFF_SIZE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Max packet size for EP0, see usb_config.h&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Vendor ID&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product ID: Mouse in a circle fw demo&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0003, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device release number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Manufacturer string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device serial number string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Number of possible configurations&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;//Class specific descriptor - HID mouse&lt;/p&gt; &lt;p&gt;ROM struct{BYTE report[HID_RPT01_SIZE];}hid_rpt01={&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {0x05, 0x01, /* Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, /* Usage (Mouse) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, /* Collection (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, /* &amp;nbsp;Usage (Pointer) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, /* &amp;nbsp;Collection (Physical) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Buttons) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Minimum (01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Maximum (03) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (3) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Absolute) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (5) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Constant) &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (X) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (Y) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (-127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (8) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Relative) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, 0xC0}&lt;/p&gt; &lt;p&gt;};/* End Collection,End Collection &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 의 소스는 분석하지 않고 특징적인 몇개의 파일만 열어보고 위의 부분에 주목하고 닫아 버린다. 역시 컨셉은 물리 마우스가 아니라 가상 마우스이기 때문이다. 가상 마우스는 연결되면 오른쪽 아래의 트레이에 연결되었다고 풍선글이 떠야 하는 형태로 진행되어야 하는 것이 머리속의 구상이었다. 이미 driveronline 의 힌트에서 pnp 를 통해서 usb 를 인식시키라는 내용을 보았고 osronline 에서는 vhidmini 의 특정부분을 언급했으며 osronline 의 최초 질문자는 샘플의 포맷과 디스크립터를 언급했다. 다음의 사이트를 보게되면 약 90% 의 감이 오게되는데 임베디드 계통이 역시나 제일 확실하다. 시스템 프로그래머라는 황무지(wild)에서 살아가는 사람들이기 때문이다. 다만, 숫갈로 퍼먹여 주는걸 제일 싫어해서 짜증난다. 다음의 KELP 사이트의 글을 보면(http://kelp.or.kr/korweblog/stories.php?story=07/02/13/3453938)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;글쓴이가 usb mouse 구현시 뭔가 이상하다는 식으로 적어놓고 있는 내용을 볼 수 있는데 한번 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb slave 포트를 이용하여 usb mouse를 구현하고 있습니다.&lt;/p&gt; &lt;p&gt;글쓴이 : omayaro (2007년 02월 13일 오후 02:10) 읽은수: 643&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;커널 2.6.11에서 gadget api를 이용하여 usb 마우스를 구현해 보고 있습니다.&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;처음에 모듈을 등록하기 위하여&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;static int __init my_module_init(void)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;int retval;&lt;/p&gt; &lt;p&gt;retval = usb_gadget_register_driver( &amp;amp;g_ugdDriver );&lt;/p&gt; &lt;p&gt;if (retval)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;printk(KERN_ERR &amp;quot;[ omayaro ] module_init: cannot register gadget driver, ret=%d\n&amp;quot;, retval);&lt;/p&gt; &lt;p&gt;return retval;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;return 0;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에서 처럼 하여 등록을 마쳤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 pc( window xp 와 fedora core4 를 사용하는 pc 2대를 한번씩 테스트 함 )에&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb cable을 연결하였습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그랬더니 임베디드 보드와 pc에 몇가지 반응이 오더군요..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래의 내용은 진짜 마우스를 꼽았을때에 windows xp에서 usb descriptor를&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;분석한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x08 (8)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0000&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x01&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x02&lt;/p&gt; &lt;p&gt;Open Pipes: 1&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Endpoint Descriptor:&lt;/p&gt; &lt;p&gt;bEndpointAddress: 0x81&lt;/p&gt; &lt;p&gt;Transfer Type: Interrupt&lt;/p&gt; &lt;p&gt;wMaxPacketSize: 0x0004 (4)&lt;/p&gt; &lt;p&gt;bInterval: 0x0A&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 아래의 정보는 제가 짠 프로그램이 동작하여 pc에 등록된 정보입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x03&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x10 (16)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0199&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x00&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x00&lt;/p&gt; &lt;p&gt;Open Pipes: 0&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;보시면 ConnectionStatus에 들어 있는 정보가 좀 틀리고 end point의 정보는 아예 없는 것을 보실수 있습니다.. 이 내용을 분석한 제 생각으로는 일단 Open Pipes의 수가 0인 것으로 보아 우선 정상적으로 연결 실패.. 가난 것으로 보이고요 end point가 없는 것으로 보아 어떤 설정또는 ep0를 통하여 세팅중에 에러가 난 것으로 보입니다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 질문...( 서론이 좀 길었죠??ㅡㅜ;;;; ) 제가 아직 usb 에 대해 정확히 이해를 못해서 인지는 몰라도 usb ep0를 통하여 setup이 될때 어떤 순서로 setup이 이루어 지는지 잘 모르겠습니다. 제 생각으로는&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. host가 device descriptor를 요청하여 가져감&lt;/p&gt; &lt;p&gt;2. 나머지 descriptor( configure, interface )를 가져감&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;으로 생각이 되는데요.. 순서가 저렇게 되는 것이 맞나요?? 그리고 pipe( 제 생각에는 in/out end point )가 open되는 시점이 이 언제인지 궁금합니다.. 조금 정리해서 물어본다면.. usb device가 pc에 꽂힌 후 정상 인식 되기까지 host가 device에게 요청하는 메시지의 순서가 궁금하네요~~ 그리고 언제 pipe가 오픈이 되는 지... 도 궁금합니다~~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;고수님들의 답변 기다릴게요~~&lt;/p&gt; &lt;p&gt;하루에 refresh만 5천번하는.. omayaro 였습니다...ㅠ0ㅠ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오케이.. 뭔가 삘이오는데.. 바로 앞에서 가슴속에 담아둔 그거네.. -_-; 중요한건 바로 디스크립터(descriptor) 컨피겨(configure) 인터페이스(interface) 라는 내용이 또 나온다. 어쨌거나 저쨌거나 질문자는 실패한 사람이니까 믿을게 못된다. 여기에 달린 댓글이 중요하다. 그런데.. 역시나.. 멋진 시스템 프로그래머들 같으니라구.. ㅎㅎ 직접읽어보라.. 민망하다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;익명 (2007년 02월 13일 오후 10:08)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 밥은 직접 떠서 드세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; device 연결시점에서는 default(첫번째) configuration 으로 동작합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; host 쪽에서 사용자의 요구에 의해 다른 configuration 으로 전환합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 흔한 경우는 아닙니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 이런 방식을 사용하는 대표적인 경우는 device 쪽에 end point 가 모자랄 경우입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 간혹, host쪽 사용자에게 디버깅 포트등을 숨기기 위해서 사용하기도 합니다.&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;역시나 댓글한번 멋지게 달려있었다. 밥은 직접 떠먹어야 한다는 말. 누가 그걸 모르나. 이쯤되면 검색에 이골이 나기 일보직전이 되고 서서히 자신감도 사라지고 짜증이 섞이기 마련이다. 이때한번 refresh 가 필요한데 검색은 계속되어야 한다.. 쭈~욱.. 점점 검색하다보면 Filter Driver 에 대한 내용이 나오기도 하고 처음부터 검색이 되더라도 알아먹지 못했던 내용이 두번째 검색하다 모르고 똑같은걸 또 보게되면(즉, 본걸 나중에&lt;/p&gt; &lt;p&gt;또 봤을때) 이해가 되기 시작하는 부분이 생겨나기 시작한다. 바로 다음의 부분들이 그러한 부분들이라 하겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;bodnar&lt;/p&gt; &lt;p&gt;February 11th, 2007, 05:58 AM&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am trying to fix a part of the report descriptor on an existing USB HID device that woked fine but&lt;/p&gt; &lt;p&gt;has problems on Vista. It installs&lt;/p&gt; &lt;p&gt;and everything is OK with it but DirectX refuses to see it due to some inconsistency in the report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I understand that I would need to write a filter driver to fix that.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have downloaded recent WDK and looked at the samples, specifically HID\Firefly sample but I cannot figure out&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;how to alter&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Report Descriptor data when the driver receives IRP_MN_START_DEVICE in DispatchPnP. I can see how PDEVICE_OBJECT&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DeviceObject is passed&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;to it but mmm.. how do I get access to HID device details so I can alter it?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;When I look inside HID\Vhidmini virtual HID minidriver I can see exactly what I would want to use in the&lt;/p&gt; &lt;p&gt;filter driver:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am a bit lost... Any help is appreciated.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;미국말로 뭐라 지껄이는지 전혀 관심없다. 오로지 Report Descriptor data when the driver receives IRP_MN_START_DEVICE&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;in DispatchPnP 라는 문장과 다음의 소스 두부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 글에서 필자가 어느타임에 어디를 수정해야 할지 방향을 구체적으로 잡아나갈 수 있는 단초가 마련되기 시작한다. 즉, DispatchPnP 에서 IRP_MN_START_DEVICE 를 받았을때 Report Descriptor data 가 관계가 있다는 점이고 ReportDescriptor 를 NewReportDescriptor 로 할당하는 조작을 잡아낼 수 있다. 원래는 vhidmini 라는 Microsoft 사의 공식샘플이 어떻게 생겨먹었는지&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;잠시 소스 일부분을 보자면&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Store the registry report descriptor in the device extension&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReadReportDescFromRegistry = TRUE;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength =&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(USHORT)RegistryReportDescriptorLength;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위의 모습처럼 되어있다. 그런데 저 미국아가 한 짓은 deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor 를 NewReportDescriptor 로 바꿨다는 것이다. 그러니 필자도 역시 이 부분을 건드리게 될 것이란 소리가 된다. 그러므로 수정을 가할 부분을 한 부분 구체적으로 알아먹었다. 이 글의 맨 처음 시작부분의 Numega Soft 의 소스라고 되어있는 부분을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;해당 부분을 보면 이제서야 뭔가 감이 오기 시작하게 되는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드디어;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.01.28:15.25 (일)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; rechoco&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 &amp;nbsp; &amp;nbsp; 487&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hid minidriver 테스트 살짝 성공~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;샘플소스를 구해서 레포트 디스크립터랑 익스텐션 조금 손만 본거지만.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;디바이스에서 데이터를 hid포멧에 맞춰서 주는게 아니라서..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;강제로 제가 바꿔줘야 했거든요ㅋ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;마우스로 테스트 해봤더니 쭉쭉 잘옮겨지더군요&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;물론 목표한 디지타이져는 아직 안됩니다;;&lt;/p&gt; &lt;p&gt;(와컴것 분석했더니 절대좌표모드일때도, 마우스 플래그를 쓰더군요&lt;/p&gt; &lt;p&gt;xp에서는 디지타이져가 지원이 안되니까 절대좌표 &amp;quot;처럼&amp;quot; 마우스좌표로 작업합니다.&lt;/p&gt; &lt;p&gt;저도 그렇게 하긴했는데. 영 개운하지가 않아서;;&lt;/p&gt; &lt;p&gt;디지타이져가 비스타에서는 지원 된다길래 해봤는데 실패했다는;;)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;제가 참고한 샘플은 WDK의 vhidmini 소스입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;xp용으로 inf파일하고 소스파일 조금 수정하시면 빌드도 잘되고..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헛짓거리중에 잠깐 들러봤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버 온라인님들 모두 화이팅하세요!!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아쉽게도 이 글은 가상 마우스인지 실제 마우스의 필터드라이버를 만든것인지 알길이 없어서 단지 말 그대로 희망만 주는 글인데 되긴 되나부다 정도로만 넘겨야 했다. 중요한 개념가닥을 잡아내는 파편과도 같은 내용들은 모두 끝났고(사실 더 많지만..) 다음의 세가지 정보의 검색이 사실상 전체적인 개념(컨셉)을 모두 얻도록 해주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;1. http://www.eggheadcafe.com/software/aspnet/32296449/virtual-usb-mouse-device.aspx&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual USB Mouse Device only shows as generic HID device. - tomca&amp;gt;&lt;/p&gt; &lt;p&gt;08-May-08 05:16:00&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I wrote a bus driver that generated virtual USB PDO for Printer, Scanner, and&lt;/p&gt; &lt;p&gt;SmartCard. &amp;nbsp;It worked fine before. &amp;nbsp;Recently, I was requested to provide a&lt;/p&gt; &lt;p&gt;virtual USB mouse PDO. &amp;nbsp;What I did was as following steps&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. An usermode application access bus driver to add a new PDO&lt;/p&gt; &lt;p&gt;2. bus driver use IoCreateDeviceSecure to create a new device and invalid&lt;/p&gt; &lt;p&gt;bus relation.&lt;/p&gt; &lt;p&gt;3. PNP manager found this new device, it will query the hardwareid, device&lt;/p&gt; &lt;p&gt;instanceid, and compatible id.&lt;/p&gt; &lt;p&gt;4. I provide USB\Class_03&amp;amp;SubClass_01&amp;amp;Prot_02 as compatible ID&lt;/p&gt; &lt;p&gt;5. System find this is a HID device and start to query Device Descriptor,&lt;/p&gt; &lt;p&gt;Configuration Descriptor, and HID descriptor.&lt;/p&gt; &lt;p&gt;6. Since this is a virtual mouse, bus driver gives HID descriptor without&lt;/p&gt; &lt;p&gt;hardware. &amp;nbsp;I copy a standard mouse device&amp;#39;s HID descriptor (3button usb&lt;/p&gt; &lt;p&gt;mouse) to caller.&lt;/p&gt; &lt;p&gt;7. From Device Manager, I can see a HID device shows up, &amp;nbsp;but there is not&lt;/p&gt; &lt;p&gt;mouse device shows up.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If I plug in a real usb mouse, I can see system create a HID device first,&lt;/p&gt; &lt;p&gt;then HIDClass driver create a PDO for mouhid driver. &amp;nbsp;Is anyting wrong I did?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have carefully checked the USB data sent to caller, everything is ok, but&lt;/p&gt; &lt;p&gt;system doesn&amp;#39;t like this device as mouse, &amp;nbsp;Just consider it as generic USB&lt;/p&gt; &lt;p&gt;HID device.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Could someone give me help?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Thanks!&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;유저모드&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;2. KSP(www.ksyspro.org) 라는 곳에서 작성한 &amp;quot;USB강의자료.PDF&amp;quot; 라는 파일이 인터넷에서 검색되었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;내용의 제목은 &amp;quot;9차 정기 세미나 강의 자료&amp;quot; USB Device Driver 강의였다. 아쉽지만 원래 이런&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;사이트는 문이 닫혀있다. (원래 그런거니까 이해를 해야한다.. -_-; 얼마나 힘들겠는가..? )&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 내용이 작살이다. 이건 그냥 인터넷에서 받아서 보라.. 전체적인 개념정립이 이루어진다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;(아마 앞서서 했던 기본적인 검색뻘짓이 없이는 읽을 수 있는 내용이 아니었으리..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;3. MSDN &amp;amp; ReactOS 소스 중의 USB 부분에 있는 Mouse 드라이버&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 항상 마지막은 MSDN 의 승리이다. 전체적인 모든 내용이 다 들어있다. 빌어먹을 일정수준이상이&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;되지 않으면 처음에 백날봐도 못알아 처먹는다는 것이 문제다. 커널이던 응용프로그래밍이던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이건 차이가 없다. 지금도 응용프로그래밍도 못알아 먹는게 태반이니까. 어쩔수 없이 이 고생을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;치르는건 MSDN 을 보기위해서가 아닐까. (COM 프로그래밍도 MSDN 이 제일 많은 정보가 있다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이 말을 증명해보겠음!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;다음은 MSDN 의 vhidmini.h 라는 파일에 능구렁이처럼 맨 마지막 부분에 주석으로 처리되어있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[vhidmini.h 파일]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;/*&lt;/p&gt; &lt;p&gt;//&lt;/p&gt; &lt;p&gt;// Here is sample descriptor that has two top level collection - mouse&amp;nbsp;&lt;/p&gt; &lt;p&gt;// collection and &amp;nbsp;vendor defined collection with a custom feature item. If&amp;nbsp;&lt;/p&gt; &lt;p&gt;// you want to provide sideband communication with your hidmini&amp;nbsp;&lt;/p&gt; &lt;p&gt;// driver, you can add a custom collection with the collection provided&amp;nbsp;&lt;/p&gt; &lt;p&gt;// by the hardware and open the custom collection from an app to&amp;nbsp;&lt;/p&gt; &lt;p&gt;// communicate with the driver.&lt;/p&gt; &lt;p&gt;// 여기 두개의 탑레벨 모음인 샘플 디스크립터가 있다.&lt;/p&gt; &lt;p&gt;// 커스텀 피처아이템을 가진 마우스 모음과 벤더 정의 모음이다.&lt;/p&gt; &lt;p&gt;// 니가 만약 너의 hidmini 드라이버를 가지고 사이드 밴드 통신을 제공하길&lt;/p&gt; &lt;p&gt;// 원한다면, 너는 하드웨어에서 제공되는 모음과 응용프로그램으로부터 드라이버&lt;/p&gt; &lt;p&gt;// 통신하는 것까지 개인모음을 추가할 수 있다.&lt;/p&gt; &lt;p&gt;// (역주: 즉, 몬소리냐면 이거 앞에서 선언한 DefaultReportDescriptor 대신에&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이걸 그냥 가져다가 써라. 마우스 예제다. 이 말이나 마찬가지임.&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;여기에 니가 원하는거 추가해서 쓰라는 소리임. 이미 소스에 다 있었음.)&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; //Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; //Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; //REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; //Usage (Pointer),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; //Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; //Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; //Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; //Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; //Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; //Logical Maximum (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; //Report Count (3),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; //Report Size (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; //Input (Data, Variable, Absolute), ;3 button bits&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; //Report Count (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x05, &amp;nbsp; &amp;nbsp; //Report Size (5),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; //Input (Constant), ;5 bit padding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; //Usage (X),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; //Usage (Y),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x81, &amp;nbsp; &amp;nbsp; //Logical Minimum (-127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x7F, &amp;nbsp; &amp;nbsp; //Logical Maximum (127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; //Report Size (8),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; //Report Count (2),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x06, &amp;nbsp; &amp;nbsp; //input (Data, Variable, Relative), ;2 position bytes (X &amp;amp; Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x06,0x00, 0xFF, &amp;nbsp; // USAGE_PAGE (Vender Defined Usage Page) &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // COLLECTION (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85,0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_ID (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // LOGICAL_MINIMUM(0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x26,0xff, 0x00, &amp;nbsp; // LOGICAL_MAXIMUM(255) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75,0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_SIZE (0x08) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_COUNT (0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xB1,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // FEATURE (Data,Ary,Abs) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// END_COLLECTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자.. 이제 끝났다~ 라고?&lt;/p&gt; &lt;p&gt;한숨을 쉬기에는 너무 이르다. 대부분의 혼선과 문제점은 여기서부터 시작되기 때문이다. Microsoft 사의 WinDDK 라는 개발킷에 있는 vhidmini 샘플은 그저 샘플일 뿐이기에 정상작동이 되는지 확인을 해야하기 때문이다. 필자는 위에서 주석처리 되어있는 마우스 예제 DefaultReportDescriptor 의 주석을 풀고 기존에 있던 샘플 DefaultReportDescriptor 와 교체했다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버를 컴파일하는 방법은 여기서 설명하지 않는다. 그냥 WinDDK 설치후 프로그램 메뉴에서 XP 용 콘솔창을 열고 vhidmini 디렉토리로 이동후 nmake 명령을 내리면 컴파일이 가능한 것을 여기서 구차하게 다 설명을 할순없다. (그러면서도 벌써 설명까지 다 해주는 친절한 금자씨.. ㅎ) 이제 vhidmini 드라이버를 컴파일하고 장치를 인스톨 시키면 오른쪽 화면아래 트레이에 드라이버가 인식되었다고 뜰 것을 기대했다. 우리가 흔히 새 마우스를 USB 포트에 꽂으면 장치가 검색되었다고 뜨는걸 볼 수 있지 않은가? Human Interface Device(휴먼인터페이스장치) 어쩌구라는 메시지와 함께 잠시뒤에 마우스가 발견되었다는 식의 그런 메시지를 기대했다. 그러나 결과는 참담했고 미궁속으로 계속해서 빠져들고 말았다. 왜 그랬을까..? 비단 이 문제는 필자만의 문제가 아니었다. vhidmini 샘플 드라이버를 처음접하는 모든 프로그래머들이 모두 이같은 삽질의 미궁속에 빠져든다는 점을 검색을 통해서 알 수 있었다. 바로, MS 의 함정을 말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 다시 위와 같은 오류를 범해나가는 설명을 할 것이다. 어떤식으로 접근할 것인가와 얼마나 많은 뻘짓이 필요했는가에 대해서 설명할 필요가 있다고 본다. 그로인해서 얻은 것들은 상당히 많이 있다. 바로 단거리 스피드로 달리는 사람들은 놓칠수 있는 정보를 마라토너들은 두루두루 보고 달릴수 있는 것처럼 주변지식들을 충분히 얻을수 있다는 장점이 있다. 이 문서를 쓰는것 자체가 사실 기술적인 것에 너무 치우치는 쪽 보다는 학습방법을 알리는 병행효과를 얻기위한 것이기 때문에 무엇을 보았는지 지금부터 과정을 설명할 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞서서 우리는 가상마우스를 만들기 위해서는 Virtual HID Device 를 만들수 있어야 한다는 점만 인식하고 출발했다. 완전히 지식이 전무한 상태에서 기본 골격코드마져 없는 허당상태로 시작할 수 있는 프로그래머는 아무도 없다. 이미 가상마우스 프로그램을 만들어본 경험이 있는 프로그래머라도 기본적인 코드의 골격없이 모든걸 직접 작성하는걸 기대하는건 어려운일이란 얘기이다. 그래서 우리가 앞에서 선행작업을 한 것이 바로 그 뼈대를 찾기위한 작업이었고, 숱한 오류과정을 거치며 우리가 만들 가상장치의 핵심뼈대를 발굴하고 비교 분석하여 선정하는 작업까지 마쳤다. 그리고 우리가 만들 장치에서 가장 중요한 핵심키포인트를 잡아내는 학습방법까지 소개하였다. 결론적으로 앞에서 습득한 사항들을 요약해 보자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. 우리가 만드는 Virtual HID Device 는 mouse 또는 keyboard 와 혼합형태(혹은 단독일수도.. 그건 선택사항)이며 가상 USB 를 통해서 장치가 인식되어야 한다. 이 점은 프로그래밍적으로 정보를 수집하기 전에 머리속으로 구상한 내용에 속한다.(나중에 언급하겠지만 실제 설치/작동은 프로그래머의 상상과 약간 다르다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;2. 여러 정보들을 수집하여 비교분석 한 뒤 그 중에서 vhidmini 라는 Microsoft 사의 WinDDK 개발킷 공식샘플을 채용하기로 최종결론을 내렸다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;3. vhidmini 라는 샘플을 운용하기위해 요구되는 스킬은 USB 의 HID 라는 인터페이스이며 이 인터페이스의 핵심 키포인트는 바로 Report Descriptor 라는 Descriptor 를 어떻게 기술할 것인가에 달려있다는 점을 알아낼 수 있다. 이 점은 이미 학습방법으로 어떻게 그 특징을 캣치하는지 보여주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;4. 우리는 최종적으로 Virtual HID Device 를 마우스로 인식시키기위해 Report Descriptor 라는 기술자(descriptor)를 찾아내야 했으며 적당한 기술자를 vhidmini.h 에서 발견하였다. 이 기술자를 Default 로 맞추고 컴파일 한 뒤 VMware 에 설치된 윈도우에서 설치하면 실제장치로 인식된다는 것까지 모두 정립하였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;다음의 명령어를 이용해서 장치를 설치할 수 있다. 즉, 윈도우가 설치된 VMware 에는 vhidmini.sys 와 vhidmini.inf 그리고 devcon.exe 라는 총 세개의 파일이 복사되어야 한다. devcon 이라는 툴은 윈도우 장치관리자가 할 수 있는 모든 기능+ 를 콘솔에서 명령내릴수 있도록 해주는 커맨드유틸이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[설치명령]&lt;/p&gt; &lt;p&gt;devcon install vhidmini.inf &amp;quot;{D49F883C-6486-400a-8C22-1A9EF48577E4}\HID_DEVICE&amp;quot; 위와 같이 VMware 에 컴파일된 vhidmini 드라이버 파일들을 모두 복사한 뒤에 설치명령을 내린다. VMware 의 화면에는 신뢰를 받지못한 장치 드라이버 설치시에 뜨는 경고문구가 뜨게될 것이다. &amp;lt;계속&amp;gt; 이라는 버튼을 클릭하게되면 sys 파일을 찾지못해 디렉토리 지정창이 한번 더 뜰 것이다. 그 이유는 현 설치위치(devcon 명령어 실행디렉토리 위치) 밑에 i386 이라는 디렉토리에 sys 파일이 존재한다는 가정을하기 때문이다. 즉, INF 파일이 존재하는 위치를 기준으로 그 하위 i386 디렉토리에서 드라이버파일을 찾는다. 그래서 드라이버를 못찾는다는 창이 뜨게된다. 이건 그냥 적당히 vhidmini.sys 파일이 있는 디렉토리를 지정하면 알아서 설치가된다. 그런데.. 우리가 예상했던 설치모습이 아니었다. 그건 필자만의 착각이었을런지도 모르겠지만, 일단 이렇게 장치의 설치과정은 밍밍하게 끝나버린다. 이제 장치가 제대로 인식되었는지 확인을 하기위해 &amp;quot;장치관리자&amp;quot; 를 오픈한다. 그러면 휴먼인터페이스 장치쪽에 두가지 장치가 새롭게 추가되어있는 것을 보게될 것이다. 그런데, 뭔가 생각하던것과는 다르게 인식된 듯한 생각을 가지게 될 것이다. 그 장치는 그저 Generic HID 장치일 뿐 마우스가 아니다. 이게 도대체 어찌된 영문인가? 뭔가 잘못된 것이 있는지 확인해보고 수도없이 DefaultReportDescriptor 를 수정 해봐도 역시나 마찬가지로 마우스로 인식되질 않았다. Revert to snapshot 을 수도없이 반복하며 디스크립터 (Report Descriptor) 를 수정해도 역시나 반응은 일반장치(Generic HID) 일 뿐이었다. 정확히 말하면 VMware 기준으로 XP 에서 장치를 설치했을때 설치되는 이름은 두가지였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;HID 준수장치&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;quot;Root Enumerated HID Device (sample)&amp;quot;&lt;/p&gt; &lt;p&gt;위의 두가지 장치가 설치된다. 우리가 원하는 것은 &amp;quot;HID 준수장치&amp;quot; 가 &amp;quot;HID 규격 마우스&amp;quot; 로 인식되어야만 한다. 그런데, 이런현상이 계속 지속되어 혼란이 가중될 뿐이었다. 어딘가 필자가 모르는 키포인트가 또다시 존재할 것이리라 생각하고 이 현상을 겪는 어딘가에 있을 동지에게 SOS 를 날려야 했다. 우리의 구글형님이 그러한 고충을 겪는 사람들을 모두 한자리로 집합시켜주었다. 그런데.. 구글이 불러모은 검색정보들은 하나 같이 모두 헛소리들 뿐이었다. 근접은 했어도 정답이 하나도 없는게 아닌가.. 제길.. FireFox 에서 탭을 약 20개 가까이 띄워놓고 검색에 검색을 반복하며 필자의 Report Descriptor 정보중 어디가 잘못되었는지를 찾아내기 위해서 안간힘을 쓰고 있었다. Report Descriptor 라는 것은 무엇인가? USB 라는 장치가 자기의 정보를 상위장치에 넘겨서 인식되도록 하기위한 마치 신분증과도 같은 것이다. 어디서 태어났고 어디서 자랐으며 나이는 몇살이고 남성인지 여성인지 기타등등.. 마치 이런정보처럼 인식정보를 쏘기전에 셋팅하는 값이다. 이 값이 하나라도 잘못될 경우에 장치는 절대로 제대로 인식되지 않는다. 항상 사람이 고생을 하려면 깨닫는 과정에서 착각을 일으키게된다. 필자는 vhidmini.h 파일에 있는 공식적인 마우스(예제) 디스크립터 주석을 풀어서 대체시켰다. 필자는 그 디스크립터를 믿지 못했다. 어딘가 오류가 있거나 한가지를 수정함으로&lt;/p&gt; &lt;p&gt;인해서 다른것까지 수정해야하는 문제점이 걸렸다거나 그런류로 생각할 수 밖에 없었다. 다음은 필자와 같은 문제점을 겪는 사람들에 대한 이야기다. 그다지 위안도 되지 않았고 결국 구글형님을 통해 문제의 정확한 해결점을 찾아낼 수 없었지만.. 그 과정에서 문득 떠오르는 영감을 주었기에 그 과정을 그려보고자 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2007-03/msg00258.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;thank for your advice.&lt;/p&gt; &lt;p&gt;i forget to assign REPORT_ID for each report desc.&lt;/p&gt; &lt;p&gt;It works now.&lt;/p&gt; &lt;p&gt;However, i migrated the corrected report to &amp;quot;hidfake&amp;quot;. (Walter Oney &amp;#39;s sample)&lt;/p&gt; &lt;p&gt;The system pop up 3 &amp;quot;Found New Device Wizard&amp;quot; window and identfy it as &amp;quot;Unknow Device&amp;quot;.&lt;/p&gt; &lt;p&gt;Any difference detween these 2 drivers&amp;#39; enumeration?&lt;/p&gt; &lt;p&gt;Appreciated.&lt;/p&gt; &lt;p&gt;(필자요약: REPORT_ID 를 빼먹었다. 작동된다. 그런데 hidfake 꺼를 배꼈다. 그랬더니 &amp;quot;알려지지않은 장치&amp;quot; 라는 새로운 장치로 &amp;quot;하드웨어 찾기&amp;quot; 가 세개나 뜬다. 나머지는 해석할 필요 없겠다.. 왜 그런가? 라는 질문 이라고 생각하고 넘어간다..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;quot;Doron Holan [MS]&amp;quot; wrote:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; you only need one HID minidriver. from it, a keyboard and a mouse can&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; be&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; enumerated. you just have to put each device into its own top level&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; collection. If you are having trouble, i would find a USB HID that already&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; does this and look at its HID descriptor&lt;/p&gt; &lt;p&gt;(필자요약: 이놈이 다른 게시판에도 있는걸보면 좀 하는거 같다. 대충 번역하면 너는 오직 한개의 HID 미니드라이버만 필요할 뿐이다. 그리고 키보드나 마우스가 열거될수 있는 것으로 부터, 그리고 각각의 그 자신의 탑레벨 모음속에 각장치들을 넣어야만 한다. 만약 문제가 있다면, 니가 만든 USB HID 를 어쩌구 저쩌구.. 뭔가 HID Descriptor 와 연관이 있겠거니하고 그냥 넘어감..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;I&amp;#39;m pretty sure you will need to break up hte device into a Mouse device and Keyboard device. (i.e two drivers,&lt;/p&gt; &lt;p&gt;one with a report descriptor for a keyboard and one for a mouse)&lt;/p&gt; &lt;p&gt;The inf files should not refer to HID\MyVirtualHidDevice - these id&amp;#39;s need to be picked up from keyboard.inf or&lt;/p&gt; &lt;p&gt;msmouse.inf - idealy reporting the compatible id of HID_SYSTEM_KEYBOARD or HID_SYSTEM_MOUSE (i think)&lt;/p&gt; &lt;p&gt;(필자요약: 마우스와 키보드장치속에 hte 장치를 깨야할 필요가 있다라고 해석해야 하나.. &amp;nbsp;이놈이 주장하는 내용은 일단, report descriptor 에 키보드와 마우스가 하나로 일치되어있는가를 확인하라는 내용과 HID\MyVirtual HidDevice 라는 장치명으로 되어있는 vhidmini.sys 샘플이 이름이 잘못되어서 그런게 아니냐는 속임수에 빠지기 쉬운 의견을 제시해 놓고 있다. 마치.. 네이버 지식인인가? 하지만 여기서 얻을 수 있는 점이 있는데 HID_SYSTEM_KEYBOARD, HID_SYSTEM_MOUSE 라는 지시어이다. 어설픈건 혼란을 가중시키는데 원래는 HID_DEVICE_SYSTEM_KEYBOARD 이고 HID_DEVICE_SYSTEM_MOUSE 가 맞는거니까 속지말자. 뒤에서 설명하겠지만 이걸 알아 듣기 위해서 새로운 개념을 습득하게 된다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Hi,&lt;/p&gt; &lt;p&gt;I write a HID minidriver with standard Mouse and Keyboard report&lt;/p&gt; &lt;p&gt;descriptors.&lt;/p&gt; &lt;p&gt;It is based on vhidmini in Windows Server 2003 DDK.&lt;/p&gt; &lt;p&gt;The driver work fine and I can read/write the report from the&lt;/p&gt; &lt;p&gt;device.&lt;/p&gt; &lt;p&gt;The Device Manager shows it is HID-compliant device in HID class,&lt;/p&gt; &lt;p&gt;but&lt;/p&gt; &lt;p&gt;the&lt;/p&gt; &lt;p&gt;Mouse Class and Keyboard Class have none.&lt;/p&gt; &lt;p&gt;How should I do so that it can be a mouse device and keyboard&lt;/p&gt; &lt;p&gt;device?&lt;/p&gt; &lt;p&gt;Should I modify the INF file? My driver&amp;#39;s INF is almost same as the&lt;/p&gt; &lt;p&gt;vhidmini&amp;#39;s.&lt;/p&gt; &lt;p&gt;(필자요약: Windows Server 2003 DDK 로 vhidmini 를 만들었다는 식인데 장치명이 HID-compliant(일반 복합HID 장치)로 인식되는데 마우스 클래스와 키보드 클래스가 없다고 말한다. 어떻게 마우스와 키보드 장치로 인식시키는 것이냐고 물어본다. 자기가 INF 파일을 수정해야 하는지 물어본다. 그리고 INF 파일은 vhidmini 와 거의 같다고 말한다. 이 사람이 겪는 증상이 필자가 겪는 증상과 100% 일치한다. 그런데 불행히도 이 글에는 더이상의 답변이 달려있지 않았다. 눈물의 고배를 마시고 돌아서야 하는 이 저린마음.. T.T 어쩔수 없이 또다시 구글형님의 도움을 받아야한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이 질/답들에서 배운 것은 검증해봐야하는 대상들이다. 일단, HID Report Descriptor 가 잘못되었는지 검증해야하며 INF 파일이 잘못되었는지 검증해봐야하고 &amp;quot;한참을 헤메게 만든 요인이었지만&amp;quot; REPORT ID 에 대해서도 검증해봐야 한다는 몇가지 결론을 얻은채 새로운 검색활로를 모색해보게 된다. 이 검색은 첫 발을 내딘수준에 불과하다. 거의 48시간을 오로지 이 문제를 해결하기 위해서 정보들을 모아야 했다.&lt;/p&gt; &lt;p&gt;http://www.techtalkz.com/microsoft-device-drivers/297875-loading-driver-hid-class.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Loading a driver on HID class&lt;/p&gt; &lt;p&gt;Hi all,&lt;/p&gt; &lt;p&gt;I have a USB device that exposes a HID interface. It is not a mouse or&lt;/p&gt; &lt;p&gt;a keyboard, just a general HID device. Device Manager displays it as a&lt;/p&gt; &lt;p&gt;&amp;quot;HID-compliant device&amp;quot;.&lt;/p&gt; &lt;p&gt;Now I would like to install a device driver on it and use the HID&lt;/p&gt; &lt;p&gt;interface to communicate with.&lt;/p&gt; &lt;p&gt;My INF refers the HID\VID_xxxx&amp;amp;PID_xxxx string and my driver gets&lt;/p&gt; &lt;p&gt;loaded.&lt;/p&gt; &lt;p&gt;So I get the PDO from AddDevice and I need the FileObject to&lt;/p&gt; &lt;p&gt;communicate using IOCTL_HID_SET_FEATURE and IOCTL_HID_GET_FEATURE. But&lt;/p&gt; &lt;p&gt;I cannot retrieve it; I use the FireFly sample and the function&lt;/p&gt; &lt;p&gt;FireflyOpenStack to retrieve the FileObject form the PDO but it fails&lt;/p&gt; &lt;p&gt;in my driver with error 0xC000000E (STATUS_NO_SUCH_DEVICE) when&lt;/p&gt; &lt;p&gt;calling ZwOpenFile.&lt;/p&gt; &lt;p&gt;What&amp;#39;s wrong? The pdoName of the file open by ZwOpenFile is something&lt;/p&gt; &lt;p&gt;like &amp;quot;\Device\00000096&amp;quot;. Is it possible to get the SymbolicLinkName&lt;/p&gt; &lt;p&gt;instead?&lt;/p&gt; &lt;p&gt;If someone could help...&lt;/p&gt; &lt;p&gt;Thanks, Roger&lt;/p&gt; &lt;p&gt;(필자요약: HID 인터페이스를 노출하는 USB 장치를 만들었다. 그런데 그게 마우스나 키보드가 아니네? 단지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;일반 HID 장치인거야. 디바이스 디스플레이에 보면 &amp;quot;HID-compliant device&amp;quot; 라고 표시되네.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;횽님들.. 알려주십쇼.. 뭐 이런 내용식으로 글을 써놨다. 그래도 아는게 많은 사람이라서 그런지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;정보들을 많이 뿌려놨는데 독이되는 요소들이 있지만, 덤으로 알게되는 요소들도 그 못지않게&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;많다. IOCTL_HID_SET_FEATURE 과 IOCTL_HID_GET_FEATURE 에대한 얘기는(추후 구현되어야 하는 내용)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좋은 정보임에 틀림없다. 그런데 우리가 원하는 답을 얻지는 못하고 단지 INF 파일에 VID 와&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PID 스트링이 문제의 시발점이 될수도 있지는 않은가 하는 의심을 해볼수 있다. 물론, 그게 해답은&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;아니지만 추가정보를 검색해야할 키워드로써 대상물망에 넣어두자. VID 란 벤더아이디를 의미하고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;제작사의 고유식별번호이며, PID 란 프로덕트 아이디 즉, 제품번호이겠다. 이게 하드웨어는 모두&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;고유하다고 하는데 과연 이 때문에 마우스나 키보드로 인식이 안되고 일반장치로 인식되는 것일까?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;when are you trying to open a handle? during AddDevice or&lt;/p&gt; &lt;p&gt;IRP_MN_START_DEVICE? neither will work b/c a file create can only occur&lt;/p&gt; &lt;p&gt;once the start irp has come back to the pnp manager. so to make this work i&lt;/p&gt; &lt;p&gt;would&lt;/p&gt; &lt;p&gt;a) register a custom device interface GUID&lt;/p&gt; &lt;p&gt;b) register for device interface arrivals on your custom guid. when you&lt;/p&gt; &lt;p&gt;get called, open your stack like FireFly does&lt;/p&gt; &lt;p&gt;you will also need to register for handle notifications on the file handle&lt;/p&gt; &lt;p&gt;that you open so that you can gracefully disable the device. If you use the&lt;/p&gt; &lt;p&gt;KMDF firefly sample, the WDFIOTARGET object does this for you&lt;/p&gt; &lt;p&gt;(필자요약: 답변중에 하나인데 이 답변은 질문자의 추측보다 더 가관이다. IRP_NM_START_DEVICE 나 AddDevice 등록시 (필자는 커널을 몰라서 몬소린지 모르지만 이건 아니다정도의 감은 있었다.. -_-;) 하라는 식으로 답변이 달려있는데 KMDF 까지 들먹거리는걸로 봐서는 논점에서 많이 빗나갔다. KMDF 는 새로운 드라이버 개발 프레임워크인데 질문자가 그걸 물어본게 아니다. 기존의 방법으로 설명해줘야하는 것이 옳은데 그렇지도 않았고, 너무 많은 작업을 추가하라고 주문하는거보니 필자의 생각과 달랐다. 필자의 감은 Report Descriptor 만으로도 해결될 문제라고 속삭이고 있었기 때문에 이 답은 해결책이 아니었다. 다른 답변중에는 URB 를 보내라는 말도 있었다. 모두 무시한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;지금 거론하는 필자의 문제해결 방법은 링크를 보여주면서 찾아나가는 방법을 설명하고 있다. 그렇기에 링크역시 필자가 검색해서 누른 순서대로 임을 밝힌다. 다음으로 찾은 것은 MSDN 의 설명이다. 그런데 MSDN 의 설명은 항상 깨달음을 얻은뒤에나 값진 보물이 되지 깨달음을 얻기전까지는 그저 잘 만들어진 명세서에 불과하다고 느낄때가 많다. 마치 선생님이 &amp;quot;공부하라&amp;quot;고 그렇게 들볶던 말들이 성인이 된 뒤에 &amp;quot;정답&amp;quot; 이라고 느끼는 것처럼 느낀뒤에만 알 수 있는 것들이 기록되어 있는게 MSDN 과도 같다. 왜 그땐 몰랐지? 왜 그땐 안봤지? 나중에 이런말 자주하게 될거다. ㅎㅎ 그런데.. 역시.. -_-; 이 링크를 보던 시점(현 글을 쓰는 시점기준으로 하루전)만 해도 이 링크는 그저 도움이 안되었다.&lt;/p&gt; &lt;p&gt;http://msdn.microsoft.com/en-us/library/aa487252.aspx&lt;/p&gt; &lt;p&gt;(필자요약: 설명이 잘 되있다. 읽어보라.. 해결책도 들어있다. 그런데 그냥보면 절대 모른다. 개고생하면 그때는 답이 보이지만 그냥보면 모른다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 이 사이트는 중국사이트인데 읽을수가 없다. 몇가지 좋은 키워드와 코드가 있는데 해결책은 아니고 나중에 마우스나 키보드를 구현할때 참고할 만한 코드가 아주 조금 있을 뿐이었다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 필자가 겪는 문제를 어느정도 일부분은 해결한 것 같기도하고 그렇지 않은거 같기도 한데 희한한&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 삽질을 하고 있었다. Descriptor 를 계속해서 바꿔가면서 테스트하는 것을 물어보고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 마우스와 키보드를 인식시키기 위해서 vhidmini 를 기본베이스로 디스크립터를 조작하는데 설치가&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 안된다는 그런 질문이었다. 질문양이 많아서 짤라붙이기는 못하겠다. 답글을 보자.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Adrian Schlesinger&lt;/p&gt; &lt;p&gt;xxxxxx@baum.ro&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 24 Sep 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 7&lt;/p&gt; &lt;p&gt;RE: Simulate keystrokes&lt;/p&gt; &lt;p&gt;I have detected what was wrong:&lt;/p&gt; &lt;p&gt;1. When adding the report ID item to the keyboard top-level collection, an additional byte should be returned to&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;the system at the beginning of the data, specifying that report ID.&lt;/p&gt; &lt;p&gt;2. Communication from user mode did not work because when cycling through the HID devices,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;in addition to vendor ID, product ID and version, the usage specified for the additional end point should also&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;be matched (with Vendor Usage 1), otherwise you can end up trying to call WriteFile for a handle corresponding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;to the keyboard end point.&lt;/p&gt; &lt;p&gt;(필자요약: 질문자의 답글인데 키보드 top-level collection(최상위 모음) 에 REPORT ID 를 추가할때 어쩌구 저쩌구 얘기가 나온다. 그리고 usage 라는 말도 나온다. 필자가 원하는 답이 여기에 있을 것이라고 생각하여 엄청난 검색을 통해 알게되었는데 원하는 답은 아니었다. 단지, top-level 의 개념은 중요했다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 앞에서 어떤사람이 한 질문과 똑같은 질문인듯 싶다. 왜 도대체 마우스로 인식이 안되냐.. 이 질문이다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;다음은 중요한 개념중에 하나인 Top-Level Collection 이다.&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Special Top-Level Collections (Reserved for OS use)&lt;/p&gt; &lt;p&gt;Certain HID top-level collections generate a special HID device string. In Windows 2000, Windows XP, and Windows&lt;/p&gt; &lt;p&gt;Server 2003, the top-level collections listed in Table 6 are special cased and each has an additional hardware ID.&lt;/p&gt; &lt;p&gt;Table 6 identifies these collections. The last column identifies the additional string that is added to the hardware&lt;/p&gt; &lt;p&gt;ID list.&lt;/p&gt; &lt;p&gt;Table 6: Special-Cased Top-Level Collections&lt;/p&gt; &lt;p&gt;Device Type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page &amp;nbsp; &amp;nbsp;Usage ID &amp;nbsp; &amp;nbsp; &amp;nbsp; Additional Hardware ID&lt;/p&gt; &lt;p&gt;Pointer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x02 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Joystick &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x04 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&amp;nbsp;&lt;/p&gt; &lt;p&gt;Game pad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;Keyboard &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x06 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;Keypad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x07 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;System Control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer Audio Control &amp;nbsp; &amp;nbsp; 0x0C &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(필자요약: 이게 모냐면 Top-Level Collection 이라 불리우는 입력장치유형이다. 위에서 Usage Page 와 Usage ID 라는 것이 있는데 이게 바로 Report Descriptor 에 있는 항목에 적혀있다. 이걸 어떻게 바꾸느냐에 따라서 가상장치가 마우스가 되느냐, 키보드가 되느냐 아니면 조이스틱이 되느냐를 결정한다. 멋지지 않은가? 물론, 원하는 해답은 아니다. 그러나 필수적으로 개념을 갖고가야 한다. 여기서 중요한게 있다면 입력 장치의 형태가 공유(share)모델이냐 아니면 베타적모델(독점)이냐 이다. 마우스와 키보드는 독점모델이다. 즉, 마우스와 키보드는 장치가 열려있으면 다른 프로그램이 장치를 열어서 쓰고읽는 것이 불가능 하도록 secure 모델로 처리되어있단다. 이때, 이걸 피해가려면 새로운 장치를 동일하게 하나더 만들어서 그 장치와 통신하면 이런 독점모델을 피해갈 수 있단다. MSDN 에 다 나와있다.. 전부 다~ 링크가 있었는데 FireFox 가 깨져서 다 날아가 버리는 바람에 찾을수 없지만 베타적오픈과 공유오픈이 가능한 표시가 위의 Top-Level Collection 에 일일이 나열되어 있는 정보도 찾을 수 있었다. 어쨌거나 중요한건 짚고 넘어가자.. 참고로 잊지는 않았겠지? 가상장치가 일반장치로 인식되서 마우스 장치로 인식시키려고 뻘짓하다가 이런곳까지 당도하게 된거란 점.. 이렇게 정보들을 다양한 방법으로 얻어서 공부하는데도 웹서핑한다고 눈치주는 경우도 있다. x같은 경우지.. 이게 단순히 노는걸로 보여? 입에서 욕나오네.. 갑자기 머리에 히터가 작동되서 한번 지껄여봤습니다. 다시 집중모드로 돌아가봅시다.. ㅋㅋ)Table 13-1 &amp;nbsp; HIDCLASS-Compatible ID for Each Supported Usage지원되는 HIDCLASS 호환 아이디.. HIDCLASS 는 각 장치로 분배를 해주는 역할을 한다고 합니다. 더 자세한건 묻지마삼 다칩니다요.. 전 아는것만 얘기할 뿐임..&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Usage Page &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Usage &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Compatible ID&lt;/p&gt; &lt;p&gt;Generic desktop &amp;nbsp; &amp;nbsp; &amp;nbsp; Pointer or mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_MOUSE&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard or keypad &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_KEYBOARD&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Joystick or game pad &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (Any) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Report Descriptor Header&amp;gt;&lt;/p&gt; &lt;p&gt;앞서서 XBCD 라고 XBOX 조이스틱 에뮬레이션 드라이버에 대해서 말한적이 있습니다.&lt;/p&gt; &lt;p&gt;헤더의 USAGE_PAGE 를 잘 봅시다. 그리고 USAGE 를 봅니다.&lt;/p&gt; &lt;p&gt;// XBCD 예&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;lt;-- 요건 뭐시냐? Table 13-1 입니다욤..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- 위의 Table 6 에 Joystick 의 Usage ID 보입니껑?&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;// vhidmini.h 의 맨마지막 주석이 되어있었던 마우스예제 헤더&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp;DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Generic Desktop), &amp;nbsp; &amp;lt;-- Table 13-1 일반 데스크탑&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- Mouse 임&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- REPORT_ID 꼭 이게 값이 있는지 확인해야함.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID Tool 이라는 놈은 이 값을 빼고 보여줌.(주의!)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Logical Minimum (0),&lt;/p&gt; &lt;p&gt;여기서 Top-Level collection 이 지칭하는 의미는 상위장치입니다. 이런식으로 다중 인터페이스를 구현할 수 있는데 예를들면 마우스와 키보드를 가상장치 하나로 일타쌍피도 만들어낼 수 있습니다. 시중에 파는 키보드 중에 마우스도 있고 USB 포트도 달려있는 키보드들은 이런 다중인터페이스를 만들기위해서는 multiple top-level collection 지정을 해줘야 한다는 얘기죠. 어쨌거나.. 이러한 정보들은 얻었고 Report Descriptor 가 잘못된 것인가라고 판단해보니 전혀 아니었습니다. 오히려 첫번째 XBCD 의 헤더모습에서는 REPORT ID 가 보이지 않는데 두번째 vhidmini.h 에서는 REPORT ID 항목도 빼먹지않고 넣었고 완벽합니다. 그런데 왜.. 대체 왜!! 인식이 마우스로 되지않고 일반장치라고 잡히는 거냐 이말이죠.. 심지어는 공식사이트에서 다운로드 받은 마우스와 키보드 Report Descriptor 를 가져다가도 해봤고 직접 하드웨어에서 뽑아낸 값을 통해서도 해봤지만 모두 인식이 안되었답니다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;사실.. 위에서 언급한 내용은 탐색과정에서 추가로 얻어내는 개념들에 대해서 비중이 있었기에 설명을 하였습니다. 아마, 계속해서 같은 방식으로 설명하면 이 문서를 보면서 쌍욕을하게 될지도 모르기에 후다닥 빨리 접겠습니다. 다음은 제가 문제해결(일반장치를 마우스로 인식하게 만드는)을 하기 위해서 찾아다녔던 링크입니다. 더 많지만 추려서 올려봅니다.&lt;/p&gt; &lt;p&gt;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&lt;/p&gt; &lt;p&gt;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&lt;/p&gt; &lt;p&gt;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(결정적인 영감을 주게된 링크는 바로 다음의 링크이고 사실, 앞에서 한번 언급했었던 링크입니다.. 정확히 말하자면 해결방법을 직설적으로 말해준게 아니라, 넌 이걸 이해해야된다라고만 코드의 일부분을 언급하고 숫가락으로 떠먹여 주지는 않겠다는 인상을 풍기는 답글이지요.. 처음에는 이걸 보고도 잘 이해를 못합니다. 저만 그런건 아닐겁니다. 어떤 질문자 중에서는 프린터, 스캐너, 스마트카드를 비롯해 각종 디바이스 드라이버를 만들었다는 이력을 밝히며 저와 같은 증상때문에 고민을 하고 있는 사람도 있었으니까요.. 제가 볼때 이건 MS 의 함정입니다. 의도하지 않은 함정말입니다.)&lt;/p&gt; &lt;p&gt;https://www.osronline.com/showthread.cfm?link=138652&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;바로 이 답글이 눈을 뜬 사람에게만 통하는 핵심인 셈입니다.&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 22 Jul 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 38&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; .......&lt;/p&gt; &lt;p&gt;(필자요약: 다음의 소스코드와 ReadDescriptorFromRegistry 함수를 봐라.. 너는 이걸 이해해야할 필요가 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 라고 말하며 일부 소스를 첨부했습니다. 그리고는 아무런 추가의 말도 없습니다. 장난하는것도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니고.. -_-; 이때 아차하고 생각을 떠올리면 이 문제는 해결됩니다. 위에서 숱하게 질문하던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 외국 개발자들도 결국에는 알아냈겠지요?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;vhidmini 드라이버를 구동시키고 일반 HID 장치로 인식된 드라이버를 마우스 장치로 둔갑시키기 위해서는&lt;/p&gt; &lt;p&gt;소스를 수정해야 합니다. 바로 vhidmini.c 드라이버 소스를 수정하는 일입니다. 그것도 필자가 생각했었던&lt;/p&gt; &lt;p&gt;Report Descriptor 의 오류를 수정하는 것이 아니라 코드를 수정해야 합니다. 앞에서도 한번 언급했었지만&lt;/p&gt; &lt;p&gt;Microsoft 사의 공식 DDK 샘플소스에 오류가 있을리는 없으니까요. vhidmini.h 에 주석으로 정의되어있던&lt;/p&gt; &lt;p&gt;마우스 Report Descriptor 의 예는 오류가 없었습니다. 오류에 빠지도록 만든것은 바로 ReadDescriptorFromRegistry&lt;/p&gt; &lt;p&gt;함수에 있었습니다. vhidmini 소스를 보면 주석에 써있기를 우리는 하드코딩을 하였다라고 적혀 있습니다.&lt;/p&gt; &lt;p&gt;Report Descriptor 를 하드코딩 하였다는 것이지요. 그런데, 단순히 그냥 하드코딩으로 놔두지.. 더 많은걸&lt;/p&gt; &lt;p&gt;보여주고 싶었던지 if-else 로 두가지 처리루틴으로 나눠놓은것이 문제의 핵심이었던 것입니다. 다음의&lt;/p&gt; &lt;p&gt;소스를 보십시오.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;[vhidmini.c 소스에서 수정해야 할 부분]&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;HID Report Descriptor 를 레지스트리에서 읽어들이는 코드를&lt;/p&gt; &lt;p&gt;&amp;nbsp;하드코딩쪽으만 처리하도록 수정함.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject); &amp;nbsp;// 함정이 발생하는 지역&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 장치를 설치할때 INF 파일에 있는 Report Descriptor 가 레지스트리에 기록되고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분에서 레지스트리에 기록된 Report Descriptor 를 읽어들임.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 그러므로 백날 헤더의 Report Descriptor 를 바꿔봤자 INF 파일에 있었던 것을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 읽어들이는 꼴이 되므로 항상 &amp;quot;일반 HID 장치&amp;quot;(Generic HID Device) 가 드라이버로&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 등록될 수 밖에 없었던 것이다. 이런 제길.. 이 문제로 이틀을 꼬박 다 날렸다니..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Microsoft 는 반성하라~!! Microsoft 는 함정을 제거하라~!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 고로 이 부분으로 빠져들지 않도록 주석처리 하라..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;else{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We will use hard-coded report descriptor.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = DefaultReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Using Hard-coded Report descriptor\n&amp;quot;));&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;case IRP_MN_REMOVE_DEVICE:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // free memory if allocated for report descriptor&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분도 주석처리해야 한다. 왜냐면 레지스트리에서부터 읽어들이지 않았기 때문에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 메모리 할당이 안되어 있기 때문이다. 그냥 두어도 상관없을거 같지만 메모리 해제부분이니&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 꺼림칙하므로 되도록이면 제거하길 바란다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(deviceInfo-&amp;gt;ReadReportDescFromRegistry)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ExFreePool(deviceInfo-&amp;gt;ReportDescriptor);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; SET_NEW_PNP_STATE(deviceInfo, Deleted);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ntStatus = STATUS_SUCCESS; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; break; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이제 vhidmini 샘플을 컴파일하고 VMware 에 vhidmini.sys 와 vhidmini.inf 파일을 복사하자. 그리고 devcon 명령으로 앞서했던 것처럼 install 을 해보자. 설치를 하고나면 장치관리자의 기존에 있던 &amp;quot;HID 준수장치&amp;quot; 라는 것은 없어지고 마우스항목에 &amp;quot;HID 규격 마우스&amp;quot; 가 추가되는 것을 볼 수 있을 것이다.(ㅎㅎ 이맛을 보려고.. 밤을새고 삽질을..) 이제.. 장치관리자에서 새로 추가된 &amp;quot;HID 규격 마우스&amp;quot; 를 선택한 뒤에 속성을 보자. 속성을 선택한 뒤 &amp;quot;자세히&amp;quot; 라는 것을 클릭한다. 그리고 장치인스턴스 ID 라는 것을 보라. HID\MyVirtualHidDevice&amp;amp;Col01 라고 되어있는 것을 볼 수 있다. 또한, 일치하는 장치 ID 를 선택하면 hid_device_system_mouse 라고 되어있다. 즉, 마우스로 인식이 되었다는 것이다. 가상 HID 디바이스 위에서 마우스 장치가 인식되어 있는 것이다. 이제 가상 HID 디바이스와 어플리케이션 간에 통신루틴을 프로그래밍하고 어플리케이션의 명령에따라 상위 클래스로 IRP/URB 같은 요청을 (이거참.. 이 레이어에서는 어떤 요청을 사용해야하는 건지 또 공부해야하는군.. -_-; USB 강의 문서에 보면 상위 클래스는 URB 통신을 한다고 나와있었다..) 날려주면 키보드나 마우스 같은 장치들을 에뮬레이션 시킬수 있다. 곧, 가상장치를 조종할 수 있다. 하지만? 그리 쉽지는 않을 것이다. vhidmini 샘플에는 testvhid 라는 어플리케이션 소스도 같이 들어있는데 이 testvhid 소스는 어플리케이션단에서 vhid miniport 드라이버와 통신하는 예제이다. 참고로 아무런 수정없이 샘플만 컴파일해도 어플리케이션과 드라이버 사이에 제대로 통신이 이루어지지않는다. 역시나 이 문제는 HID Report Descriptor 의 데이타의 구성문제에 속한다. 한번 고생한 것이 또다시 반복되는 시점이기도 하다. 이 부분을 해결하면 어플리케이션은 2 또는 3 가지의 top-level collection 중에서 사용자정의(User-Defined) 콜렉션을 통해서 miniport 드라이버와 통신을 할 수 있게되고 이 통신에 따라서 마우스 IRP 를 상위 클래스로 때려주면 된다. 더 자세한 내용은 스스로 연구하길 바란다. 이상으로 이번문서를 마무리하려고 한다. 왜냐면 이제 테스트 기반이 마련되었으니 나머지 추가구현은 스스로가 해야할 몫이기 때문이다. 어떠한 목적으로 개발하던간에 그 이상은 이제 필자가 관여할 부분이 아닌것 같다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어차피 이 문서의 목적은 가상 마우스를 제작하는 것을 중점으로 삶는 것보다도 모르는 분야를 독학하며 개척해 나갈때 자신의 공부스타일의 한 예로써 제시하는 것이었다. 여기서 거론된 공부스타일을 종합해 본다면 이렇게 말할 수 있을것 같다. &amp;quot;관례를 찾아냄으로써 DIFF 를 추출해내는 공부법&amp;quot; 이라고 할 수 있다. 즉, 최대한 많은 자료들을 검색으로 긁어모은 뒤에 분리분석 작업을 통하여 동일한 부분의 반복을 찾아낸다. 찾아낸 반복내용이 있다면 결국 그 반복은 해당 프로그래밍의 관례에 속한다. 즉, 해당 관례는 몸으로 빨아들이고 차이가 나는 지점에서 기술을 흡수한다. 이런식의 반복학습을 통하여 더이상 다른 코드나 정보들을 찾아낼 수 없다고 판단이 들때 그 기술은 자기것이 된다. 필자는 유저레벨을 공부할때 항상 이방식을 택해왔다. 정보가 고갈되고 더이상 찾아낼수 없을때까지 긴시간을 할애해서 리서치를 먼저 한다. 그 뒤에 코딩으로 들어간다. 그리고 관례코드를 따른다. 그렇게되면 생전 처음보는 프로그래밍에서도 어느지점은 건드려도 되고 어느지점은 절대 건드려서는 안되는지 쉽게(? 정확히가 맞겠다) 익힐수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제는 커널레벨 공부를시작하면서 이 고통스럽고도 지루한 공부방식을 다시 사용하고자하며 다른 사람에게 조그마한 도움이 되고자 이런 문서를 작성하였다. (같이 게임에 미쳐서 광랩하던 친구가 갑자기 URL 을 려줘서 읽어 보았더니 국가에서 인증한 기술이라는 자랑스런 인증서와 함께 뭔가를 팔고있었다. 보란듯이 대놓고 말이다. 디자인도 쌈빡해서 사고싶게 만드는 그것.. 그게 뭔지는 대충 말안해도 알겠지만.. 이 문서를 빨리 공개해야하겠다는 생각이 들었다. 원래는 문서를 다 작성해놓고도 공개하지않는 방향으로 생각을 굳혔다가 아무래도 생각이 바뀌기 시작하였다. 그 이유는 뒷부분의 부록을 보라..) 아마 이 방식으로 공부하는 사람들이 많겠지만 그렇지 않을수도 있을 것이다. 적어도 이렇게 공부할땐 뼈를 깎듯이 힘들지만 원하고자 하는 지식을 얻으면 그 지식의 깊이가 뼈속으로 스며들 것이다. 필자처럼 어떤 새로운 분야에 공부를 시작하거나 공부하는 방법을 몰라서 물어보려는 사람들이 있다면 이 문서를 읽어보라고 말하고 싶다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;잡설&amp;gt;&lt;/p&gt; &lt;p&gt;필자가 만약에 커널디버깅을 잘 다뤘다면 아마도 쉽게 문제를 해결했을지도 모르겠다. 하지만 필자는 귀차니즘 때문에 커널디버깅을 좋아하지 않았고 결국, 공부도하지 않았다. (요즘들어 먹고 살라니.. 공부중이다.. -_-;) 그런데 필자는 오히려 디버거를 쓰지 않으면 않을수록 프로그램에 대한 이해도는 높아진다고 생각한다. 왜냐면 사람의 머리는 충분히 상황을 시뮬레이션 할 수 있다고 생각하기 때문이다. 에뮬레이션은 불가능하겠지만 시뮬레이션은 가능하다. 그리고 이 작업을 통해서 문제가 발생되는 지점을 캣치할 수 있다고 생각한다. 그렇게 되었을때 남보다 더 느릴지 몰라도 이해도는 훨씬더 깊이있는 굴곡을 생성해낸다고 생각한다. 어쩌면 그렇게 믿고싶은 것일지도 모르겠다. 적어도 자신은 그렇게 소신을 갖고있다. 그렇다고 커널디버깅을 배우는 것을 말리거나 도외시하라는 것은 절대 아니다. 필수적으로 갖고가야할 기술이라는 점에는 변함이 없지만 두가지를 모두 안배하는 것이 스스로에게 좀 더 풍요로운 지식을 가져다 줄 것이라는 점을 인지했으면 좋겠다는 의미이다. &amp;quot;Art of Hooking&amp;quot; 이라는 문서처럼 스스로의 깨달음을 전달하려고 쓴 문서는 아니지만 이 시간에도 같은 문제로 삽질하고있을 그들에게(아직도 정확한 답변을 보지 못한 질문자들이 인터넷에 깔려있음을.. 이미 보여줬다..) 이틀이라는 시간을 좀 더 귀중한 곳에 쓸 수 있도록 해줄 수 있다는 것은 행복한 일이라고 생각한다. 만약 누군가에게 이런 도움을 지속적으로 받을수 있었다면 본인은 솔로여야할 이유가 없었을 것이리라.. (아쉽게도 영어를 못하니 국내만이라도 도움을 받으면 좋을듯 싶다.) 참고로.. 이 문서는 주제를 인지하는 시점부터 해결과정을 도출해내는 모든 전 과정이 거의 실시간으로 쓰여졌다.. 그렇게 해야만이 이 문서의 목적인 &amp;quot;가상마우스&amp;quot; 와 &amp;quot;공부방법론&amp;quot; 두가지를 모두 전달할 수 있다고 판단했기 때문이다. 필자는 누군가 이 문서를 읽고 얻은게 있었다면 그것만으로 행복할 것이다. 하드에 처박혀 쓰레기가 된채 어느날 자신도 모르게 삭제되는 그런 정보가 아니라는 점만으로도 충분히 가치있는 것이니까..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록1: 필자가 생각하는 에뮬레이션과 시뮬레이션의 차이점]&lt;/p&gt; &lt;p&gt;에뮬레이션: 기계의 톱니바뀌처럼 구성요소들의 기능자체들이 모두 동일하게 작동해야 한다. (기능/작동의 동일화)&lt;/p&gt; &lt;p&gt;시뮬레이션: 기능자체를 동일하게 할 필요없이 입/출력되는 수치/값만 동일하면 된다. (수치/데이타의 동일화)&lt;/p&gt; &lt;p&gt;(필자주: 틀렸을 수도 있다. 정확하지않다. 다만, 여태까지 몸으로 와닿는 느낌자체를 말로 풀어써본 것 뿐이다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록2: 시중에 떠도는 물리형 Auto Mouse 탐지법]&lt;/p&gt; &lt;p&gt;먼저, 가상장치에 대한 것부터 언급해보고 물리형으로 넘어가겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;1. 가상장치 탐지방법&amp;gt;&lt;/p&gt; &lt;p&gt;재밌는 사실이 있는데 아는 사람은 알 것이고 모르는 사람은 모를 것이다.&lt;/p&gt; &lt;p&gt;MSPRESS 에 보면 짜가장치(FakeDevice) 탐색법이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;HANDLE CtestDlg::FindFakeDevice()&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; GUID hidguid;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; HidD_GetHidGuid(&amp;amp;hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; CDeviceList devlist(hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; int ndevices = devlist.Initialize();&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; for(int i = 0; i &amp;lt; ndevices; ++i)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HANDLE h = CreateFile(devlist.m_list[i].m_linkname, 0,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FILE_SHARE_READ | FILE_SHARE_WRITE,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(h == INVALID_HANDLE_VALUE)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HIDD_ATTRIBUTES attr = {sizeof(HIDD_ATTRIBUTES)};&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;BOOLEAN okay = HidD_GetAttributes(h, &amp;amp;attr);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CloseHandle(h);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(!okay)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(attr.VendorID != HIDFAKE_VID ||&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; attr.ProductID != HIDFAKE_PID)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return CreateFile(devlist.m_list[i].m_linkname,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GENERIC_READ | GENERIC_WRITE, 0, NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; return INVALID_HANDLE_VALUE;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;위의 짜가장치 탐색법은 골때리게 단순하다. 결국에는 HIDFAKE_VID 와 HIDFAKE_PID 를 체크하는 개념이다. 즉, 제작사(Vendor ID)와 제품번호(Product ID)를 가지고 짜가인지 판별하겠다는 개념이다. 그렇다면 제작사와 제품번호는 속일수 없다고 생각하는가? 커널을 뒤짚어 엎는(Subvert) 판국에 저렇게 단순하게 비교해서는 가상장치를 막을수 없다. 위의코드를 보고 판단을 하길 가상장치는 다 막겠다고 판단한다면 정말 큰일이다. 어처구니 없는 싸움이 키보드보안이래 또 발생할 것이기 때문이다. 위의 코드가 의미하는 바를 잘못해석하면 안된다. 위의 코드는 이렇게 해석해야 한다. 그 어떠한 가상장치를 막을수 있다는 컨셉하에 위의 코드를 만들길 시도한것이 아니라 고정장치를 알아내기위해 만들어진 컨셉이라는 점을 말이다. 단지 정형화 되어있는 즉, 고정되어있는 상태에서는 가능할 수 있겠다. 이해를 돕기위해 예를한가지 들어보자. VMware 같은 가상머신 안에서 작동하는 것인지 정도는 파악할 수 있지 않을까 싶다. 왜냐면 VMware 가 동적으로 제작사와 제품번호를 바꿔야할 까닭이 없지않은가? 다르게 말하면 VMware 가 굳이 자기 제품정보를 굳이 속이거나 변덕스럽게 수시로 바꿔야할 필요가 전혀 없다는 얘기다. 이런경우에는 마치 하드웨어처럼 고정장치로 봐도 무방하다. 고로 VMware 에는 항상 고정된 장치가 있다고 판단해도 될 것이며 VMware 안에 구현된 장치들 중에는 가상장치들이 있으므로 항상 디텍트 할 수 있단 얘기가 되므로 위의 짜가장치 탐색법은 그러한 경우에 사용할 수 있는 컨셉이라는 소리다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아직 더 깊이 연구해보지는 않았지만 가상장치와 전쟁을 선포할 경우에 또 하나의 &amp;quot;키보드보안&amp;quot; 같은 파국으로 치닫기에 좋은 스토리가 탄생할 것이다. 차라리 이것을 좀 더 유용한 곳에 사용해보면 어떨까? 바로!! 물리형 Auto Mouse 를 탐지하는 것이다. 기술은 적합한 곳에 쓰라고 있는 것이지 말도안되는 헛다리 싸움에 쓰라고 존재하지 않는다. 기술을 적용시킬때는 단순히 눈과 머리로만 판단하지말고 포괄적인 정황을 바탕으로 자신의 가슴속에 확신이 설때 비로소 본격적인 전쟁에 들어가야 한다. 그저 돈이된다고 키보드보안처럼 너도나도 발담궈놓고 아무도 책임지지않고 아무도 발도 못빼는 승자없는 싸움에 휘말리기 싫다면 필히 이 말을 웃어넘기지 말아야 할 것이다.(아마, 이젠 더이상 발을 빼지도 못할것이다.. 담구지 말라고 뜯어말려도&lt;/p&gt; &lt;p&gt;담궜으니 해야할 일은 그저 땜빵밖에 뭐가 더 있겠는가.. ㅉㅉ)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;2. 물리형 Auto Mouse 탐지&amp;gt;&lt;/p&gt; &lt;p&gt;물리형 Auto Mouse 를 탐지하는 것의 기본바탕은 앞서 짜가장치 탐색에 사용된 코드를 그대로 채용하면 되겠다. 단, 제작사와 제품번호만이 아닌 추가정보를 이용할 필요가 있겠다. 그런데, 왜 효용성이 물리형 Auto Mouse 를 탐지하는 것에 효력이 있을까? 그 이유는 간단하다. 다음과 같은 정보를 보자. 필자는 최근에 오픈된 MMORPG 온라인 게임의 Auto Mouse 를 구매해보았다. 과연 어떻게 돌아가는지 궁금증도 있었고 진짜 완벽하게 구동이 되는것인지 두눈으로 확인해보고 싶었기 때문이었다. 그런데 일단, 한군데의 제품은 구동이 제대로 안되는 것을 확인하였다. 다만, 마우스 입력이나 키보드 입력은 그대로 게임속으로 전달되고 있다는 점에 주목하였다. 과연 그러한 것을 어떻게 탐지해낼 수 있을까? 다음은 USB View 라는 프로그램으로 Auto Mouse 장치의 Descriptor 를 본 화면이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Auto Mouse HID Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;quot;USB Composite 장치&amp;quot;&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x0200&lt;/p&gt; &lt;p&gt;bDeviceClass: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x20 (32)&lt;/p&gt; &lt;p&gt;idVendor: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x03EB (Atmel Corporation)&lt;/p&gt; &lt;p&gt;idProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x4743&lt;/p&gt; &lt;p&gt;bcdDevice: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x1000&lt;/p&gt; &lt;p&gt;iManufacturer: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY&amp;quot;&lt;/p&gt; &lt;p&gt;iProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x02&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY PRO8&amp;quot;&lt;/p&gt; &lt;p&gt;iSerialNumber: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x03&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;1.0.0&amp;quot;&lt;/p&gt; &lt;p&gt;bNumConfigurations: &amp;nbsp; 0x01&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;그렇다. idVendor 가 제작사이고 idProduct 가 제품번호이겠다. 이 정보는 필자가 예상컨대 고정이라 할 수 있다. 일단, 텍스트를 주의깊게 보자. &amp;quot;Atmel Corporation&amp;quot; 이 보이는가? 해커들이 가장 많이 사용한다는 그 유명한 &amp;quot;Atmel&amp;quot; 칩이 사용되었다. 일명 FPGA 칩이라고 불리운다. 이 FPGA 칩은 프로그래밍 가능한 이점이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(사견: 언제부터 마우스가 Atmel 칩으로 제작되었던가? 그래서 오토마우스가 그리도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;비싼거였나보다.. 싸구려 PIC 칩만으로도 마우스를 만들수 있다. 전자업계는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;원래 원가전쟁을 벌이는 계통이라서 단 1원이라도 원가를 절감해 보려고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;깎고깎고 전쟁을 벌인다. 필자의 친구가 전자회사 CEO 라서 이점은 매우 잘&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;알고있다. 그 친구의 말을 빌어보자면 진짜 1원갖고 쪼잔하게 굴 수 밖에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;없다고 한다. 살아남아야 하니까 말이다.. 그런데 FPGA 칩을 쓰는 것을 보면&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좀 수상하다. 왜 재프로그래밍이 가능한 칩을 쓰는 것인가.. 재수없으면 기타장치&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;메모리스틱 리더기같은 것들이 연결되어 있을수도 있으므로 함부로 판단하기는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이르지만 아마도 대량유통되는 칩이 아닌 DIY(사제품)칩을 쓴다는 것은 기정&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;사실이라고 추측할만 하지않은가? 필자가 대에충 찾아보니 Auto Mouse 제작사&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;두군데가 Atmel 칩을 사용하고 있었다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;만약 이 Atmel 칩이 필자가 아는 것과 달리 재프로그래밍이 가능한 기능이 없다면 게임업계에서는 대박의 찬스를 잡은 것이리라.. 왜? 고정이잖은가? 고정!! 또, 재미난 정보를 볼 수 있는데 바로 그 유명하다고 하는 &amp;quot;ATPLAY&amp;quot; 라는 마크가 찍혀있다. 아주 그냥 상호를 갖다가 박아놓은거보니 장사할 생가이 없다하겠다.&lt;/p&gt; &lt;p&gt;일단, 칩이 Atmel 칩으로 제작되어있는 USB 형 물리장치들을 사용하는 사용자는 모두 감시대상순위로 집어넣어도 십중팔구는 맞아떨어질 것이다. 특히나 Atmel 칩에 상관없이 상호명 ATPLAY 가 박혀있다면 그 사용자는 거의 Auto Mouse 를 사용하고 있을 확률이 99.9% 라고 할 수 있겠다. 그리고 USB View 같은 프로그램이 사용하는 루틴들은 위에서 언급된 루틴들에서 크게 벗어나지는 않을테니 쉽게탐지할 수 있다고 감히 추측해본다. 딱한가지 우려되는 사항이 있다면 프로그래밍 가능한 칩이기 때문에 업데이트 기능으로&lt;/p&gt; &lt;p&gt;펌웨어를 갈아치울 경우에 난감하게 될 것이다. 하지만 방금 언급한 방식을 사용한다면 Auto Mouse 제작사의 미래고객이 아닌 현재 고객들은 99.9% 가 탐지된다고 봐도 무방할 것이다. 물론, Auto Mouse 의 종류별로 이짓을 해야겠지만.. 프로그래머들의 습성상 모두 식별자를 기록해놓았을테니(아마, Atmel 칩에 코딩을 의뢰하거나 혹은 Atmel 칩에 프로그램이 가능한 사람을 영입했겠지만 프로그래머들이 그런거 생각안한다. 왜냐면 원리원칙을 따르려는 프로그래머의 심리상 바보같이 위에처럼 ATPLAY 를 박는게 미덕으로&lt;/p&gt; &lt;p&gt;생각할 것이기 때문이다.) 행동만 빨리 취한다면 현재 Auto Mouse 사용자들의 태반은 모두 다 탐지해낼 수 있을 것이라고 감히 판단해본다. 즉, 물리형은 고정이라는 변수를 잘 활용할 수 있기에 탐지도 비교적 수월한 편에 속한다는 것이다. 한가지 더 재미난 상상을 해보자.. 과연 Auto Mouse 업체에서 펌웨어 업데이트 기능을 추가로 만들어내는데 얼마나 시간이 걸릴까? 누가 더 대응이 빠를까..? 과연 이 전쟁에서 Auto Mouse 업체의 대응이 빠를까? 아니면 막는자의 대응이 더 빠를까? 아마도 덩치가 작은쪽이 더 빠르겠지만 두고볼 일일 것이다. 이 전쟁은 어느한쪽의 시간전쟁일 뿐이다.. 정확하고 빠른판단이 내려지면 그대로 바로 행하는 쪽이 이기는 것이다. 현재로써 본 필자의 생각으로는 물리형 Auto Mouse 는 막을 수 있다. 이 문서가 나온 시점 앞으로가 문제이다.. 점차 Auto Mouse 는 가상마우스로 진화를 꿈꾸고 있기 때문이다. 그것이 바로 기술의 대세인 것이다. 오늘의 기술이 내일의 쓰레기가 되어버리는 시대에서 속도전의 중요함이다. 승자는 과연 누가 될까? 아무도 모른다.. 기술은 끝이 없으니까.. 마이 골치아픈 것이다.. -_-; 어디까지나.. 필자 개인이 현 상태를 진단해본 사견일 뿐이다. 이 이상 어케 더 판단하랴..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[HID Descriptor Tool]&lt;/p&gt; &lt;p&gt;USB.ORG 공식 사이트에서 받을수 있음&lt;/p&gt; &lt;p&gt;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&lt;/p&gt; &lt;p&gt;(위에서 언급한 사이트 이외 참고한 사이트)&lt;/p&gt; &lt;p&gt;http://kkamagui.tistory.com/485&lt;/p&gt; &lt;p&gt;http://www.keil.com/forum/docs/thread13037.asp&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR DeviceID[] &amp;nbsp;={L&amp;quot;ROOT\NUMEGA_VIRTUAL_HID_MOUSE&lt;/p&gt; &lt;p&gt;본 문서는 파워해커에서 제작되었으며 무단배포를 허용함..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual HID Mouse Driver 연구&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;저자: AmesianX&lt;/p&gt; &lt;p&gt;제작: powerhacker.net&lt;/p&gt; &lt;p&gt;제작년도: 2009년 1월 15일&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[서문]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;본 문서의 시작에 앞서 목적에 대해 언급한다. 이 문서는 두가지 목적을 위해서 작성되어졌다.&lt;/p&gt; &lt;p&gt;첫번째는 모르는 부분에대한 새로운 연구나 공부를 시도할때 참고할 수 있는 공부방식(Style)에 대한 설명이고, 두번째는 Virtual HID Mouse Driver 를 제작할때 참고해야할 전초를 다지기위한 목적으로 구성되어 있다. 이렇게 기술문서를 공개하는 이유에는 여러가지가 있지만 무엇보다 이 기술이라는 분야는 언젠가는 자신이 알고있는 오늘의 기술이 내일의 쓰레기가 된다. 일찌감치 알고있는 정보들은 공개하고 더 높은 곳으로 계속 뛰어오를때 진정으로 아무도 가보지못한 고지에 오른 것이다. 그래야 스스로가 발전하는 길이고 바로 모두가 발전하는 길일 것이다. 고지는 점령 당하라고 있는 것이다. 언제까지 정적인 비공개노선으로 점령당하길 기다리고 있을 것인가? 앞으로는 더욱더 가속화될 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[기술을 습득하는 공부방법]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 새로운 기술을 알고싶다면 최대한 동일기능이 구현된 많은 소스들을 수집하라. 그리고 그 차이점을 소스분석을 통해서 캣치하라. 아마 대부분은 소스분석을 깊게 들어가지 않아도 차이점이 눈에 띄게 될 것이다. 그러나.. 아쉽게도 Virtual HID Mouse 에 대한 소스는 인터넷에서 거의 찾기 힘들 것이다. 물론, 공식적인 샘플들을 찾아낼 수 있지만 필자처럼 커널지식보다 유저레벨 어플리케이션 조작만 파온 사람은 그 유명업체들의 공식샘플을 보고도 감을 잡아내기는 하늘에 별따기처럼 어렵다. 즉, 프로그래밍 = 개념 이라는 공식이 있기 때문에 이 개념만 잡고나면 프로그래밍은 껌씹기나 마찬가지다. 개념을 잡는 요령이 있다면 그것은 바로 앞에서 언급한 동일기능 소스의 차이점을 분석해내는 것이다. 그렇기 때문에 매우 제한된 소스(공식소스들)를 갖고 시작하는 것은 전혀 이해를 이끌어내지 못한다. 최대한 고갈되었다고 생각될 정도로 많은 설명이나 소스들을 검색해서 찾아내야 한다. 이때 사용할 수 있는 방법은 구해낸 소스들의 일부 시그너처(Signature)를 검색키워드로 사용하는 것이다. 이런식으로 최대한 많은 정보들을 뽑다보면 선구자들의 질문들을 찾아낼 수 있다. 바로, 그 질문들에서 핵심개념들을 뽑아낼 수 있다. 자주 언급되는 사항이 바로 그 핵심일 것이다. 어떻게보면 &amp;quot;미네르바&amp;quot; 인지 &amp;quot;미네로하이바&amp;quot; 인지 그 친구처럼 철저한 검색기술로 무장한 채로 짜집기의 달인이 되어야만 할 필요가 있다. 만약 충분히 많이 찾아서 더이상 찾아낼 것 조차 없다고 느끼고 등골이 휘어지는 고통을 여러번 견뎌내었다면 이제 얻어낸 것들을 대상으로 비교분석을 취한다. 그렇게 되면 중요 키포인트가 눈에 보이게 될 것이다. 왜 이렇게 해야 하냐면 답은 간단하다. 스스로 엄청난 고통을 감뇌하면서 충분히 검색을 했는데 다 내용이 거기서 거기인 경우가 99.9% 일 것이다. 왜? 그것은 삽질하는 프로그래머가 택한 프로그래밍 방법론은 달라도 전체적인 흐름은 재밌게도 한가지밖에 없으니까. 이게 답이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;어라? 다 똑같은 소리만 짓거리고 있잖아? 뭔가 좀 더 구체적인 것을 달라고!!&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 소리가 나올때 이미 정답은 구해진 것이나 마찬가지다. 다 똑같은 소리를 짓거린다거나 똑같은 소스에 차이점은 있지만 원하는 것이 아니라고 생각될때 사실상 그것이 원하는 것일 확률이 태반이다. 그 이상의 짜집기(Copy &amp;amp; Paste) 능력은 밥을 숫갈로 퍼서 먹는 것이다. 그런데 필자같은 사람은 퍼서 먹여주는 것을 원한다. 왜? 프로그래밍이 나온 이유가 무엇인가? 로보트를 만들려고 기를 쓰는거보면 모르겠는가? 인간에게 숫갈로 밥을 퍼먹여 주려는게 궁극적인 목적아닌가? 프로그래머는 인간이 아니었나? (하기사 혹자는 로보트&lt;/p&gt; &lt;p&gt;라고도 부릅디다..) 프로그래머는 좀 퍼서 먹여주면 어디가 덧나는가? 짜증나게 약올리는 시스템 프로그래머들이여 퍼먹여주지 않으면 스스로 밥숫갈 놓게되는 날이 온다. 인터넷시대에서 정보라는 것은 물 흐르듯 흐를수 밖에 없기 때문에 빨리 털고 높은 곳으로 뛰지않으면 숫가락 놓을 준비를 해야 할 것이다. 오늘의 신기술이 내일의 쓰레기가 되는 시대에서 서로 돕지않으면 혼자 살아남기 힘들다. 외국애들 보라 오픈소스로 자기의 기술을 다 까발리고 있으면서도 항상 최첨단 기술을 걷고 있는 것을 보면 우리가 얼마나 어리석은지 진정 모르냐 이말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;외국애들은 오픈소스를 통해서 시너지라는 것을 이용하고 있다. 물론, 수 많은 개발자들이 다 참가해서 오픈소스가 완성될 것이라고 착각하면 그건 열라 바보이다. 유명 보안 오픈소스인 Nessus 개발자의 고충이 섞인 글을 읽어보았는가? 오픈소스임에도 불구하고 자기혼자만 개발해 왔다고 써있었다. 대부분의 오픈소스들이 마찬가지라고 보면 될 것이다. 다만, 시너지효과로 인해 개발자 1명이 해낼수 있는 능력이 100명 1000명 수준으로 증폭되었기에 프로젝트가 맥을 이어갈 수 있는 것이다. 즉, 게임용어로 말하면 &amp;quot;버프&amp;quot;(버프를 모르진 않겠지..) 를 받은 것이다. 그렇게 되면 소수의 엘리트 파워가 오픈소스에 집중되는 일반유저의 관심만큼 증폭되기 때문이다. 단순히 눈에보이는게 전부라고 생각한다면 큰 것을 놓치게된다. (아니라고? 아님말고.. 허위사실 유포로 감금되어야 하나.. ㅎㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[현 상황]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현 상황에서는 Virtual HID Mouse 가 Auto Mouse 나 MACRO 라는 시장에서 대안으로 대두된 상태라 x시장에서도 드라이버의 판매가 이루어지고 있는 상황이다. 참고로 이 기술이나 드라이버를 판매자체는 사실 법적인 문제의 소지가 없다. 왜냐면 이 Virtual HID Mouse 기술은 범용기술이기 때문이다. 이 기술이 사용되고있는 쪽은 예를들면 조이스틱을 에뮬레이션하거나(용산에가면 조이스틱 판다..) 블루투스 마우스를 사용하도록 해주거나 혹은 그에 버금가는 마우스 업체들이 주로 보유하고있는 자체기술에서 많이 볼 수 있다. 이건 우리가 늘상 접하는 일반분야에서 말한것 뿐이고 무엇보다 가장 많이 사용되고 있는 곳은 임베디드 산업에서일 것이다. 그러므로 이 기술을 파는 것은 전혀 문제가 될 수 없다. 이 기술자체는 Microsoft 사에서 공식적으로 WinDDK 에 예제와 함께 배포하고 있다는 사실을 알만한 사람들은 이미 다 알고있겠다. 단지 그 이상의 자세한 정보를 찾기가 어렵고 Microsoft 사에서 제공하는 기술정보를 알기위해서 밑받침(선행) 되어야할 정보가 없다는 것이 문제점이다. 그래서 기존에 커널 드라이버를 개발하던 사람들이나 천국이지 필자같은 미천한 어플프로그래머들한테는 짜증만 나게 할 뿐이다. 이 중간에 생략된 정보들이 무엇인지 알아내야 한다. 그것이 유저레벨이라는 미천한 신분에서 커널레벨이라는 귀족신분으로 도약할 수 있는 길이다. 테스트환경 만드는게 짜증나서 공부하지 않았다가 완전 독박 쓴 기분이기에 좀 고약한 말투가 나온다. (기분 상하는 커널레벨의 고급 독자는 당장 이 문서를 접기 바란다. 필자도 커널레벨을 공부해야 윈도우를 진정으로 아는 것이라는 대에 이견이 없다. 다만, 오래전부터 블루스크린과 친구를 맺고싶지 않았을 뿐이다. 이거 참.. 뻘쭘하게 커널과 &amp;quot;절친노트&amp;quot; 라도 찍어야하나..)&lt;/p&gt; &lt;p&gt;===================================================================================================================&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현재, 인터넷에는 몇몇의 기술 정보이외에는 관련된 기술적 자료를 찾아볼 수 없다고 해도 과언이 아니다. 진짜 짜증나도록 자료가 없다. 이해를 할 수 있을만한 한글로된 기술자료는 극적으로 한개를 찾을 수 있었다. 먼저, Virtual HID Mouse 를 찾아보면 가장먼저 접하게 되는 사이트가 있다. 까마귀라는 한국사람이 자신이 만들었다고하는 Virtual HID Mouse 가 검색이 된다. 블로그의 글 내용인데 사실 저수준을 다루는 고급개발자가 아니면 볼게없다.. (왜? 필자같은 어플프로그래밍 수준은 못알아 먹으니까.. + 안갈켜주니까&lt;/p&gt; &lt;p&gt;-_-;) 그리고 MSDN 이 검색되고 vhidmini 라는 것이 검색된다. 또한, 짱개 사이트의 vhidmouse 라는 소스와 hidmouse 라는 소스도 검색된다. 근데.. 오래전에 GxxxGuard 라는 소스가 인터넷에 떴다는 그 몹쓸 짱개사이트였다. 구현을 하기 위해서는 vhidmini 라는 소스가 그중에서 제일 유력한 후보가 될 것이고 나머지 vhidmouse 와 hidmouse 는 소스를 구하는데 한참이나 걸릴 것이다. 일단, 대충 둘러서 정보를 캣치해야한다. 다음은 이미 다들 알고있겠지만 SoftICE 라는 걸작을 만들어낸 &amp;quot;Numega Soft&amp;quot; 라는 회사의 Virtual HID Mouse 공식샘플의 일부소스이다. 아쉽게도 이 소스는 Windows 9x 계열에서 작동되는 드라이버이므로 NT 계열에서는 사용할 수 없다. 하지만 캣치할 수 있는 중요한 내용이 포함되어 있다. 위에서 언급한 것중에 vhidmouse 라는 것이다. 다음은 vhidmouse 소스 중의 일부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// vmoudev.cpp - &amp;nbsp;virtual mouse device for HID example &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Compuware Corporation &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// NuMega Lab &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// 9 Townsend West &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Nashua, NH 03060 &amp;nbsp;USA &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Copyright (c) 1998 Compuware Corporation. All Rights Reserved. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Unpublished - rights reserved under the Copyright laws of the &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// United States. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// This module implements the device class of the virtual HID &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// mouse minidriver. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;lt;KHID.H&amp;gt; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;vmoudev.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;hidmouse.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;KTrace T(&amp;quot;&amp;quot;,TRACE_MONITOR, TraceAlways, BreakNever, KUstring(L&amp;quot;HidMouse&amp;quot;)); &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEX 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEY 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, // Logical Maximum (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, // Report Count (3), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, // Report Size (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, // Input (Data, Variable, Absolute), &amp;nbsp; &amp;nbsp;;3 button bits &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, // Report Count (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, // Report Size (5), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, // Input (Constant), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, // Usage (X), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, // Usage (Y), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, // Logical Minimum (-127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, // Logical Maximum (127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, // Report Size (8), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, // Report Count (2), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, // Input (Data, Variable, Relative), &amp;nbsp; &amp;nbsp;;2 position bytes (X &amp;amp; Y) &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; // End Collection, &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// End Collection &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// HardwareID for the virtual mouse. &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR HardwareID[]={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR DeviceID[] &amp;nbsp;={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_DEVICE_ATTRIBUTES DeviceAttributes = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; sizeof(HID_DEVICE_ATTRIBUTES), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VENDOR_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PRODUCT_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; VERSION_NUMBER &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; };&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같이 HID_REPORT_DEscRIPTOR 라는 것을 볼 수 있는데, 처음에는 이게 뭔지 모른다. 감도 안온다. 그러므로 그 관점을 그대로 두고 다음으로 넘어가서 다른 소스들을 보자. (처음엔 원래 모르겠지.. 나만그런가.. -_-; 제길..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;인터넷에서 검색하면 위의 소스와 MSDN (Microsoft 사의 공식샘플과 설명문서) 을 먼저 보게 될 것이다. 그러면 당연히 vhidmini 라는 것도 접하게 된다. 소스는 인터넷에서 파는 놈들도 있으니 그냥 찾기는 좀 짜증이 날 것이다. Microsoft 사의 홈페이지에서 WinDDK 를 받으라. 그 안에 VHidMini 라는 샘플이 들어있다. 그놈을 보면 다음과 같이 생겨먹은 부분에 주목하자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (NT_SUCCESS(ntStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Use default &amp;quot;HID Descriptor&amp;quot; (hardcoded). We will set the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // wReportLength memeber of HID descriptor when we read the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // the report descriptor either from registry or the hard-coded&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // one.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Microsoft 에서 MSDN 의 설명을 먼저 읽어본 뒤 위의 소스주석부분을 보자. 다음과 같이 친절하게 설명해주고 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;설명에 써있듯이 자기네는 그냥 하드코딩 했으니까 ReadFromRegistry 를 참고하면 다른 디바이스를 등록할 수 있단다. 처음 접할땐 사전지식이 없기에 &amp;quot;이게 뭔 개소리야?&amp;quot; 라고 생각이 들 것이다. (? 반응이 없으면 나만그런거 같다.. ㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다면 이제 개소리는 집어치우고 다음을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--&amp;gt; &amp;nbsp;https://www.osronline.com/showthread.cfm?link=138652&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Radly&lt;/p&gt; &lt;p&gt;xxxxxx@daryllee.com&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This being my first driver project, and an unusual one at that, there&amp;#39;s a lot to get my&lt;/p&gt; &lt;p&gt;head wrapped around. My intent is to produce a virtual HID device (mouse emulation) that&lt;/p&gt; &lt;p&gt;uses a complex non-HID physical device as the input medium. I&amp;#39;m using the VHidMini sample&lt;/p&gt; &lt;p&gt;from the WDK hid folder as a starting point, and I&amp;#39;m now at the point where I need to transform&lt;/p&gt; &lt;p&gt;the sample&amp;#39;s report format into a mouse format. I notice with confusion that the report descriptor&lt;/p&gt; &lt;p&gt;in vhidmini.inf is different from that in vhidmini.h, with no explanation in vhidmini.htm as&lt;/p&gt; &lt;p&gt;to why they are different. Does anyone here have any insight on that?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 놈이 필자가 생각하는 것과 동일한 구현을 해볼려고 삽질중에 무시무시한 고급개발자들과 해커들이 몰린다는 osronline 에 질문을 던져놓고 있다. 이 소리는 무엇인가? 필자도 결국 저 문제에 봉착하게 될 날이 온다는 시나리오를 미리 발견한 것이다. 그러므로 주의 깊게 읽어볼 필요가 있다. 여기서 얻어낼 수 있는 정보는 sample&amp;#39;s report format 이란 것과 report descriptor 라는 두가지 내용이다. 원래부터 찾기힘든 정보들에는 동문서답 내지는 &amp;quot;내가 니 밥처먹는데 밥숫가락으로 퍼먹여주랴?&amp;quot; 정도의 댓글이 달리는데 그래도 이 글의 답글중에 괜찮은 답글이 있다. 근데.. 여전히 찾기힘든 정보만큼이나 짤막하게 달아놓는다. 이런사람이 있다는 것은 희망이고 곧 빛이다. 다음의 답글을 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;입에서 욕은 나온다. 왜? 말할라면 다 말하던가 아니면 동문서답이나 하고 가던가 감칠맛나게 소스 네줄 뿌리고 튀다니.. 그래도 고맙다. 지식을 갈구하는 자에게는 이것조차 선물이다. 제길.. 현자라면 푸념할때가 아닌거 같다. 여기서 뭔가 개념을 잡을 수 있는 정보를 캣치해야만 한다. 이 글에서 외국아가(짱개류 외국애인지 allen zhang 이구나.. 역시 중국은 AUTO 에 강한가보다..) 말하기를 소스코드를 보란다. 그 안에 ReadDescriptorFromRegistry 를 보라고 권하면서 일부 소스를 긁어서 보여준다. 글은 짧지만 분명 소스를 열어봤기에 긁어서 붙여줬을테니 아쉬워도 고마운 행동이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 보라고 한 소스가 바로 위에서 VHidMini 샘플의 일부분이라고 뿌린 부분이다. 즉, 이 부분의 내용은 최초 질문자의 글에서 캣치한 sample&amp;#39;s report format 와 report descriptor 라는 부분에대한 응답이다. 즉, 이 함수의 이름으로부터 알 수 있듯이 레지스트리로부터 디스크립터를 읽어들인다는 것에 바로 Virtual HID Mouse 의 핵심구현이 얽혀있다는 것을 시사한다는 점을 알 수 있다. 그런데 필자도 단지 이두개만 가지고 감을 잡지는 못했다. 왜냐면, 커널을 깊이 공부한 적이 없는 사람이 이 두가지의 자료만을 토대로 감을 잡아낼 수 있겠는가? 그렇다면 그건 천재이거나 영어를 모국어처럼 잘하는 사람일게 분명하다. 필자는 남보다 항상 두배로 삽질을 하는데 머리가 남들보다 딸려서 그렇다. 자료도 항상 두배로 찾아야 한다. 결정적으로 힌트가 되었던 것은 역시 국내사이트인데 드라이버 개발정보를 알려주는 곳인 driveronline.org 에서의 힌트와 임베디드 계통의 KELP 사이트에서 였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://driveronline.org/bbs/view.asp?tb=beusb&amp;amp;GotoPage=1&amp;amp;s_bulu=memo&amp;amp;s_key=pnp&amp;amp;no=1491&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Re] Re] Re] USB 가상 키보드, 마우스 드라이버&lt;/p&gt; &lt;p&gt;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.10.02:10.40 (화)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; Woof&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 605&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;pnp 를 이용해서든지 해서 가상적인 usb 장치가 인식이 되면 일반적인 usb 장치를 다루듯이 이용하시면 됩니다. 일반적으로 실제 장치들은 &amp;nbsp;Windows에서 제공하는 기본적인 드라이버로도 동작하기 때문에 필요가 없지만 이와 같은 경우에는 간단하게 자기 드라이버를 열어서 인식된 장치 device와 통신하는 드라이버 정도는 필요하겠지요. 뭐, usb라서 따로 드라이버없이 application으로도 충분히 가능한건데 다들 위와 같은 방법을 이용하더군요. 새로나온 umdf 등을 이용하면 더 간단하고 새로나온 것에 대한 공부도 하면서 재미나게 할 수 있을지도 모르겠네요. 위 에서 말한 대부분의 경우 라고 한 것의 예를 간단히 들어보면 자신의 드라이버를 올리고 해당 드라이버에서 application과 통신 device를 생성한 뒤에 pnp를 이용해서 가상적인 usb 장치를 만들고 그것과 통신하는 길?을 적당히 만들어서 이용하시면 됩니다. sample에서는 가상적인 장치 인식이 바로 usb나 그런 부분이 아니였던 것 같은데 적당히 고치면 되겠지요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에도 썻지만, 잘 찾으면 다 만들어진 코드 어디 있을 것 같습니다. 저도 한번 찾으려다가 그냥 sample에 있어서 말았는데. :| &amp;nbsp;해당 usb 드라이버를 이용해서&amp;quot; 라는 부분에 대해서 물어보셔서 이 부분만 따로 답을 달면 해당 usb device를 제어(control)하는 드라이버를 지칭했습니다. &amp;nbsp;또 처음에 말한 것 처럼 class관련 드라이버에 대해서는 생각할 필요가 없습니다. 역시 위에 쓴 것 처럼 어디에 쓰실지 궁금하네요. 가상 키입력등은 S/W나 그런 자동화 테스트에 이용하기도 하고 꽤 여러군데서 쓰기는 하는데 안좋지는 않지만 뭐 . 그런데도 쓰여서 :|&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;최초 질문자가 어떻게 구현해야 하냐고 질문하자 pnp 를 통해서 가상적인 usb 를 인식시킨 다음에 적당히 device 와 통신시키라고 한다. 자세한 내용은 말해주지 않고 Microsoft 에서 제공하는 샘플로도 구현이 가능할 것이라는 내용과 어딘가에는 이미 다 만들어진 소스가 있을텐데 찾아보라고 한다. 이말 믿고 인터넷에서 찾아헤메다가는 마누라가 집나가도 모를것이다. 답변에서 보듯이 이 사람은 진짜 적당히 답글을 달고 있는 사람이라는 점을 주의해야 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 사람의 힌트와 통찰력이 Microsoft 사의 샘플에서 존재하는 핵심이라는 점을 알 수 있다. 일단, 정보는 머리속에 꼬깃꼬깃 담아두고 계속 다음 검색으로 넘어가면서 본인의 마음속에 답이 한가지로 수렴되도록 정보들을 계속 얻어 내어보자. 이쯤되면 정상적인 사이트를 뒤지는 것이 힘들어진다. 왜냐면 너무 정보가 부족하기 때문이리라. 고로 컨트롤러를 제어하는 것을 찾아본다. 예를들면 USB HID 조이스틱 드라이버 같은 것을 찾아내는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;다음과 같은 좋은 예가 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.redcl0ud.com/files/XBCD_all_src.cab&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBOX 의 6축 조이스틱 패드를 윈도우에서 사용할 수 있도록 해주는 소스였다. 검색을 할때는 기존에 얻었던 소스에서 일부 특이하게 보일만한 함수를 키워드로 검색하면 운좋게 찾을 수 있다. 소스를 보면 너무 길고 난해하고 이해하기 힘들뿐이다. 당연히 커널관련 지식이 깊지않은 이상 어떻게 분석하고싶어도 그럴 도리가 없다. 그러므로 파일구성을 보는 것이 전부이다. 여기서 또한가지 힌트를 얻을 수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBCD_control.c&lt;/p&gt; &lt;p&gt;XBCD_driver.c&lt;/p&gt; &lt;p&gt;XBCD_driver.h&lt;/p&gt; &lt;p&gt;XBCD_hid.h&lt;/p&gt; &lt;p&gt;XBCD_report.h&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 파일구성에서 driver 나 control 소스를 보기전에 report 라는 눈에 띄는 놈이 있다. 이 헤더파일의 내용을 보게되면 다음과 같은 것이 적혀있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x05, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 5)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x06, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 6)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 9)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0a, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 10)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0b, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 11)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0c, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 12)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Cnst,Ary,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x16, 0x01, 0x80, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (-32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (X)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Simulation Controls)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xba, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Rudder)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xbb, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Throttle)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x39, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Hat switch)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0x3b, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (315)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x65, 0x14, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; UNIT (Eng Rot:Angular Pos)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0d, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 13)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0e, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 14)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 15)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Not Defined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x91, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; OUTPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xc0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // END_COLLECTION&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 이 홈페이지에서 최대한 얻을 수 있는 것은 다 캣치해야 하는 http://www.redcl0ud.com/xbcd.html 홈페이지의 마지막쯤에 보면 http://www.redcl0ud.com/files/USBView.cab 라는 것이 있다. 그리고 캡춰사진이 있는데 핵심사항으로 체크를 해둔 부분이 있다. idVendor, idProduct 라는 부분에 체크를 해두고 있다. 그리고 USBView 에서 보여주는 내용이 모냐면 바로 Device Descriptor 였다. 오호라.. 내친김에 이 사이트에서는 USB 드라이버를 제작하는 방법까지 설명하는 링크를 걸어두고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://euc.jp/periphs/xbox-controller.en.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 링크인데 제목은 &amp;quot;Inside XBox Controller&amp;quot; 라고 되어있다. 대충 무슨내용이 있는지 열거하자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;lt;Inside Xbox Controller&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Overview&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;USB Device Model&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Descriptors&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here are descriptor dumps of the hub, the gamepad and the memory unit.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the integrated hub&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the gamepad (American)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the memory unit&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Vendor/Product IDs&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The vendor ID is 0x045e (Microsoft). Product IDs are as follows:&lt;/p&gt; &lt;p&gt;ID &amp;nbsp; &amp;nbsp;product&lt;/p&gt; &lt;p&gt;0x001c &amp;nbsp; &amp;nbsp;integrated hub&lt;/p&gt; &lt;p&gt;0x0202 &amp;nbsp; &amp;nbsp;gamepad (American)&lt;/p&gt; &lt;p&gt;0x0280 &amp;nbsp; &amp;nbsp;memory unit&lt;/p&gt; &lt;p&gt;0x0284 &amp;nbsp; &amp;nbsp;DVD remote receiver&lt;/p&gt; &lt;p&gt;0x0285 &amp;nbsp; &amp;nbsp;gamepad (Japanese)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;It is not recommended to distinguish Xbox gamepads by vendor/product IDs because third-party controllers may&lt;/p&gt; &lt;p&gt;have their own vendor/product IDs.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Device Class&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;HID Report Format&amp;gt;&lt;/p&gt; &lt;p&gt;Input Report&lt;/p&gt; &lt;p&gt;The input report is 20-byte.&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Output Report&lt;/p&gt; &lt;p&gt;The output report (rumble control) is 6-byte.&amp;nbsp;&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Example of HID Report Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;The Xbox gamepad lacks the HID report descriptor that describes the input/output report formats. Based on the&lt;/p&gt; &lt;p&gt;above report formats I have tried writing the report descriptor for your information. This is a mere example;&lt;/p&gt; &lt;p&gt;neither official nor verified. Accuracy is not guaranteed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Text format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Binary format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * HID Descriptor Tool format (to be loaded into HID Descriptor Tool)&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 내용들이 있었다. 상당히 많은 삘을 주고있다. 누가봐도 HID Descriptor 와 HID Report Format 그리고 Input Report 와 Output Report 를 통해서 통신한다는 아주 기본적인 컨셉(개념)은 머리가 아니라(T.T) 가슴에 와닿을 것이다. (젠쟝.. 가슴에만 담아두마.. -_-;) 일단, 이쯤에서 XBCD 소스는 닫아둔다. 언제 이거 분석하고 앉아있는가.. 최종컨셉이 다르기 때문에 힌트만 뽑아먹고 닫아두는 것이다. 애초에 만들려고 한건 Virtual HID Mouse 인데 이건 그 컨셉이 아니기에 대충 훑어보고 넘겨야 한다. 또 다른 소스들을 보자. 마구잡이로 검색하면서 받아둔 소스중에 앞에서 처음에 말했던 hidmouse 라는 소스를 한번 진단해보자.. -_-;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(PIC 를 이용한 마우스 제작소스)&lt;/p&gt; &lt;p&gt;파일을 열어보니 원하는게 아닌듯 보였는데 알고보니 PIC 용이었다. 운 좋게도 필자는 PIC18x 롬라이터를 갖고 있어서 이 소스가 뭔지 알 수 있었다. 오래전에 친구의 부탁으로 PIC18x 칩에 어셈블리를 롬라이팅 하는 프로그램을 만들어준 적이 있어서 무슨 소스인지 금방 알 수 있었다. 요새는 PIC 프로그래밍에도 C 가 쓰이고 PIC 는 PLC 대체용으로 쓰이기도 한다. 그런데 PIC 로 USB 모듈을 부착하고 마우스로 제작이 가능한거 같았다. 어쨌거나 원하는 내용은 아니었지만 생각해보면 가장 중요한 것이 물리적인 장치 아닌가? 물리적인 장치에서는 기존에 찾은 소스들이나 검색내용들과 어떤 차이가 있는지 알아볼 필요도 있다.&lt;/p&gt; &lt;p&gt;http://www.pudn.com/downloads128/sourcecode/comm/detail543439.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 라는 소스에서 파일구성을 보면 특이한 놈이 있다.&lt;/p&gt; &lt;p&gt;usb_descriptors.c 라는 소스가 있는데 여태까지 눈여겨왔던 descriptor 라는 단어가 보일 수 밖에 없다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;/* Device Descriptor */&lt;/p&gt; &lt;p&gt;ROM USB_DEVICE_DEscRIPTOR device_dsc=&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x12, &amp;nbsp; &amp;nbsp;// Size of this descriptor in bytes&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_DEscRIPTOR_DEVICE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// DEVICE descriptor type&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0200, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USB Spec Release Number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Class Code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Subclass code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Protocol code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_EP0_BUFF_SIZE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Max packet size for EP0, see usb_config.h&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Vendor ID&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product ID: Mouse in a circle fw demo&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0003, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device release number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Manufacturer string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device serial number string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Number of possible configurations&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;//Class specific descriptor - HID mouse&lt;/p&gt; &lt;p&gt;ROM struct{BYTE report[HID_RPT01_SIZE];}hid_rpt01={&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {0x05, 0x01, /* Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, /* Usage (Mouse) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, /* Collection (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, /* &amp;nbsp;Usage (Pointer) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, /* &amp;nbsp;Collection (Physical) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Buttons) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Minimum (01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Maximum (03) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (3) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Absolute) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (5) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Constant) &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (X) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (Y) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (-127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (8) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Relative) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, 0xC0}&lt;/p&gt; &lt;p&gt;};/* End Collection,End Collection &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 의 소스는 분석하지 않고 특징적인 몇개의 파일만 열어보고 위의 부분에 주목하고 닫아 버린다. 역시 컨셉은 물리 마우스가 아니라 가상 마우스이기 때문이다. 가상 마우스는 연결되면 오른쪽 아래의 트레이에 연결되었다고 풍선글이 떠야 하는 형태로 진행되어야 하는 것이 머리속의 구상이었다. 이미 driveronline 의 힌트에서 pnp 를 통해서 usb 를 인식시키라는 내용을 보았고 osronline 에서는 vhidmini 의 특정부분을 언급했으며 osronline 의 최초 질문자는 샘플의 포맷과 디스크립터를 언급했다. 다음의 사이트를 보게되면 약 90% 의 감이 오게되는데 임베디드 계통이 역시나 제일 확실하다. 시스템 프로그래머라는 황무지(wild)에서 살아가는 사람들이기 때문이다. 다만, 숫갈로 퍼먹여 주는걸 제일 싫어해서 짜증난다. 다음의 KELP 사이트의 글을 보면(http://kelp.or.kr/korweblog/stories.php?story=07/02/13/3453938)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;글쓴이가 usb mouse 구현시 뭔가 이상하다는 식으로 적어놓고 있는 내용을 볼 수 있는데 한번 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb slave 포트를 이용하여 usb mouse를 구현하고 있습니다.&lt;/p&gt; &lt;p&gt;글쓴이 : omayaro (2007년 02월 13일 오후 02:10) 읽은수: 643&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;커널 2.6.11에서 gadget api를 이용하여 usb 마우스를 구현해 보고 있습니다.&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;처음에 모듈을 등록하기 위하여&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;static int __init my_module_init(void)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;int retval;&lt;/p&gt; &lt;p&gt;retval = usb_gadget_register_driver( &amp;amp;g_ugdDriver );&lt;/p&gt; &lt;p&gt;if (retval)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;printk(KERN_ERR &amp;quot;[ omayaro ] module_init: cannot register gadget driver, ret=%d\n&amp;quot;, retval);&lt;/p&gt; &lt;p&gt;return retval;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;return 0;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에서 처럼 하여 등록을 마쳤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 pc( window xp 와 fedora core4 를 사용하는 pc 2대를 한번씩 테스트 함 )에&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb cable을 연결하였습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그랬더니 임베디드 보드와 pc에 몇가지 반응이 오더군요..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래의 내용은 진짜 마우스를 꼽았을때에 windows xp에서 usb descriptor를&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;분석한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x08 (8)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0000&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x01&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x02&lt;/p&gt; &lt;p&gt;Open Pipes: 1&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Endpoint Descriptor:&lt;/p&gt; &lt;p&gt;bEndpointAddress: 0x81&lt;/p&gt; &lt;p&gt;Transfer Type: Interrupt&lt;/p&gt; &lt;p&gt;wMaxPacketSize: 0x0004 (4)&lt;/p&gt; &lt;p&gt;bInterval: 0x0A&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 아래의 정보는 제가 짠 프로그램이 동작하여 pc에 등록된 정보입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x03&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x10 (16)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0199&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x00&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x00&lt;/p&gt; &lt;p&gt;Open Pipes: 0&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;보시면 ConnectionStatus에 들어 있는 정보가 좀 틀리고 end point의 정보는 아예 없는 것을 보실수 있습니다.. 이 내용을 분석한 제 생각으로는 일단 Open Pipes의 수가 0인 것으로 보아 우선 정상적으로 연결 실패.. 가난 것으로 보이고요 end point가 없는 것으로 보아 어떤 설정또는 ep0를 통하여 세팅중에 에러가 난 것으로 보입니다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 질문...( 서론이 좀 길었죠??ㅡㅜ;;;; ) 제가 아직 usb 에 대해 정확히 이해를 못해서 인지는 몰라도 usb ep0를 통하여 setup이 될때 어떤 순서로 setup이 이루어 지는지 잘 모르겠습니다. 제 생각으로는&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. host가 device descriptor를 요청하여 가져감&lt;/p&gt; &lt;p&gt;2. 나머지 descriptor( configure, interface )를 가져감&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;으로 생각이 되는데요.. 순서가 저렇게 되는 것이 맞나요?? 그리고 pipe( 제 생각에는 in/out end point )가 open되는 시점이 이 언제인지 궁금합니다.. 조금 정리해서 물어본다면.. usb device가 pc에 꽂힌 후 정상 인식 되기까지 host가 device에게 요청하는 메시지의 순서가 궁금하네요~~ 그리고 언제 pipe가 오픈이 되는 지... 도 궁금합니다~~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;고수님들의 답변 기다릴게요~~&lt;/p&gt; &lt;p&gt;하루에 refresh만 5천번하는.. omayaro 였습니다...ㅠ0ㅠ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오케이.. 뭔가 삘이오는데.. 바로 앞에서 가슴속에 담아둔 그거네.. -_-; 중요한건 바로 디스크립터(descriptor) 컨피겨(configure) 인터페이스(interface) 라는 내용이 또 나온다. 어쨌거나 저쨌거나 질문자는 실패한 사람이니까 믿을게 못된다. 여기에 달린 댓글이 중요하다. 그런데.. 역시나.. 멋진 시스템 프로그래머들 같으니라구.. ㅎㅎ 직접읽어보라.. 민망하다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;익명 (2007년 02월 13일 오후 10:08)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 밥은 직접 떠서 드세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; device 연결시점에서는 default(첫번째) configuration 으로 동작합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; host 쪽에서 사용자의 요구에 의해 다른 configuration 으로 전환합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 흔한 경우는 아닙니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 이런 방식을 사용하는 대표적인 경우는 device 쪽에 end point 가 모자랄 경우입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 간혹, host쪽 사용자에게 디버깅 포트등을 숨기기 위해서 사용하기도 합니다.&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;역시나 댓글한번 멋지게 달려있었다. 밥은 직접 떠먹어야 한다는 말. 누가 그걸 모르나. 이쯤되면 검색에 이골이 나기 일보직전이 되고 서서히 자신감도 사라지고 짜증이 섞이기 마련이다. 이때한번 refresh 가 필요한데 검색은 계속되어야 한다.. 쭈~욱.. 점점 검색하다보면 Filter Driver 에 대한 내용이 나오기도 하고 처음부터 검색이 되더라도 알아먹지 못했던 내용이 두번째 검색하다 모르고 똑같은걸 또 보게되면(즉, 본걸 나중에&lt;/p&gt; &lt;p&gt;또 봤을때) 이해가 되기 시작하는 부분이 생겨나기 시작한다. 바로 다음의 부분들이 그러한 부분들이라 하겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;bodnar&lt;/p&gt; &lt;p&gt;February 11th, 2007, 05:58 AM&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am trying to fix a part of the report descriptor on an existing USB HID device that woked fine but&lt;/p&gt; &lt;p&gt;has problems on Vista. It installs&lt;/p&gt; &lt;p&gt;and everything is OK with it but DirectX refuses to see it due to some inconsistency in the report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I understand that I would need to write a filter driver to fix that.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have downloaded recent WDK and looked at the samples, specifically HID\Firefly sample but I cannot figure out&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;how to alter&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Report Descriptor data when the driver receives IRP_MN_START_DEVICE in DispatchPnP. I can see how PDEVICE_OBJECT&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DeviceObject is passed&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;to it but mmm.. how do I get access to HID device details so I can alter it?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;When I look inside HID\Vhidmini virtual HID minidriver I can see exactly what I would want to use in the&lt;/p&gt; &lt;p&gt;filter driver:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am a bit lost... Any help is appreciated.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;미국말로 뭐라 지껄이는지 전혀 관심없다. 오로지 Report Descriptor data when the driver receives IRP_MN_START_DEVICE&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;in DispatchPnP 라는 문장과 다음의 소스 두부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 글에서 필자가 어느타임에 어디를 수정해야 할지 방향을 구체적으로 잡아나갈 수 있는 단초가 마련되기 시작한다. 즉, DispatchPnP 에서 IRP_MN_START_DEVICE 를 받았을때 Report Descriptor data 가 관계가 있다는 점이고 ReportDescriptor 를 NewReportDescriptor 로 할당하는 조작을 잡아낼 수 있다. 원래는 vhidmini 라는 Microsoft 사의 공식샘플이 어떻게 생겨먹었는지&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;잠시 소스 일부분을 보자면&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Store the registry report descriptor in the device extension&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReadReportDescFromRegistry = TRUE;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength =&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(USHORT)RegistryReportDescriptorLength;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위의 모습처럼 되어있다. 그런데 저 미국아가 한 짓은 deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor 를 NewReportDescriptor 로 바꿨다는 것이다. 그러니 필자도 역시 이 부분을 건드리게 될 것이란 소리가 된다. 그러므로 수정을 가할 부분을 한 부분 구체적으로 알아먹었다. 이 글의 맨 처음 시작부분의 Numega Soft 의 소스라고 되어있는 부분을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;해당 부분을 보면 이제서야 뭔가 감이 오기 시작하게 되는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드디어;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.01.28:15.25 (일)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; rechoco&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 &amp;nbsp; &amp;nbsp; 487&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hid minidriver 테스트 살짝 성공~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;샘플소스를 구해서 레포트 디스크립터랑 익스텐션 조금 손만 본거지만.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;디바이스에서 데이터를 hid포멧에 맞춰서 주는게 아니라서..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;강제로 제가 바꿔줘야 했거든요ㅋ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;마우스로 테스트 해봤더니 쭉쭉 잘옮겨지더군요&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;물론 목표한 디지타이져는 아직 안됩니다;;&lt;/p&gt; &lt;p&gt;(와컴것 분석했더니 절대좌표모드일때도, 마우스 플래그를 쓰더군요&lt;/p&gt; &lt;p&gt;xp에서는 디지타이져가 지원이 안되니까 절대좌표 &amp;quot;처럼&amp;quot; 마우스좌표로 작업합니다.&lt;/p&gt; &lt;p&gt;저도 그렇게 하긴했는데. 영 개운하지가 않아서;;&lt;/p&gt; &lt;p&gt;디지타이져가 비스타에서는 지원 된다길래 해봤는데 실패했다는;;)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;제가 참고한 샘플은 WDK의 vhidmini 소스입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;xp용으로 inf파일하고 소스파일 조금 수정하시면 빌드도 잘되고..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헛짓거리중에 잠깐 들러봤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버 온라인님들 모두 화이팅하세요!!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아쉽게도 이 글은 가상 마우스인지 실제 마우스의 필터드라이버를 만든것인지 알길이 없어서 단지 말 그대로 희망만 주는 글인데 되긴 되나부다 정도로만 넘겨야 했다. 중요한 개념가닥을 잡아내는 파편과도 같은 내용들은 모두 끝났고(사실 더 많지만..) 다음의 세가지 정보의 검색이 사실상 전체적인 개념(컨셉)을 모두 얻도록 해주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;1. http://www.eggheadcafe.com/software/aspnet/32296449/virtual-usb-mouse-device.aspx&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual USB Mouse Device only shows as generic HID device. - tomca&amp;gt;&lt;/p&gt; &lt;p&gt;08-May-08 05:16:00&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I wrote a bus driver that generated virtual USB PDO for Printer, Scanner, and&lt;/p&gt; &lt;p&gt;SmartCard. &amp;nbsp;It worked fine before. &amp;nbsp;Recently, I was requested to provide a&lt;/p&gt; &lt;p&gt;virtual USB mouse PDO. &amp;nbsp;What I did was as following steps&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. An usermode application access bus driver to add a new PDO&lt;/p&gt; &lt;p&gt;2. bus driver use IoCreateDeviceSecure to create a new device and invalid&lt;/p&gt; &lt;p&gt;bus relation.&lt;/p&gt; &lt;p&gt;3. PNP manager found this new device, it will query the hardwareid, device&lt;/p&gt; &lt;p&gt;instanceid, and compatible id.&lt;/p&gt; &lt;p&gt;4. I provide USB\Class_03&amp;amp;SubClass_01&amp;amp;Prot_02 as compatible ID&lt;/p&gt; &lt;p&gt;5. System find this is a HID device and start to query Device Descriptor,&lt;/p&gt; &lt;p&gt;Configuration Descriptor, and HID descriptor.&lt;/p&gt; &lt;p&gt;6. Since this is a virtual mouse, bus driver gives HID descriptor without&lt;/p&gt; &lt;p&gt;hardware. &amp;nbsp;I copy a standard mouse device&amp;#39;s HID descriptor (3button usb&lt;/p&gt; &lt;p&gt;mouse) to caller.&lt;/p&gt; &lt;p&gt;7. From Device Manager, I can see a HID device shows up, &amp;nbsp;but there is not&lt;/p&gt; &lt;p&gt;mouse device shows up.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If I plug in a real usb mouse, I can see system create a HID device first,&lt;/p&gt; &lt;p&gt;then HIDClass driver create a PDO for mouhid driver. &amp;nbsp;Is anyting wrong I did?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have carefully checked the USB data sent to caller, everything is ok, but&lt;/p&gt; &lt;p&gt;system doesn&amp;#39;t like this device as mouse, &amp;nbsp;Just consider it as generic USB&lt;/p&gt; &lt;p&gt;HID device.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Could someone give me help?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Thanks!&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;유저모드&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;2. KSP(www.ksyspro.org) 라는 곳에서 작성한 &amp;quot;USB강의자료.PDF&amp;quot; 라는 파일이 인터넷에서 검색되었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;내용의 제목은 &amp;quot;9차 정기 세미나 강의 자료&amp;quot; USB Device Driver 강의였다. 아쉽지만 원래 이런&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;사이트는 문이 닫혀있다. (원래 그런거니까 이해를 해야한다.. -_-; 얼마나 힘들겠는가..? )&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 내용이 작살이다. 이건 그냥 인터넷에서 받아서 보라.. 전체적인 개념정립이 이루어진다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;(아마 앞서서 했던 기본적인 검색뻘짓이 없이는 읽을 수 있는 내용이 아니었으리..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;3. MSDN &amp;amp; ReactOS 소스 중의 USB 부분에 있는 Mouse 드라이버&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 항상 마지막은 MSDN 의 승리이다. 전체적인 모든 내용이 다 들어있다. 빌어먹을 일정수준이상이&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;되지 않으면 처음에 백날봐도 못알아 처먹는다는 것이 문제다. 커널이던 응용프로그래밍이던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이건 차이가 없다. 지금도 응용프로그래밍도 못알아 먹는게 태반이니까. 어쩔수 없이 이 고생을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;치르는건 MSDN 을 보기위해서가 아닐까. (COM 프로그래밍도 MSDN 이 제일 많은 정보가 있다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이 말을 증명해보겠음!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;다음은 MSDN 의 vhidmini.h 라는 파일에 능구렁이처럼 맨 마지막 부분에 주석으로 처리되어있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[vhidmini.h 파일]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;/*&lt;/p&gt; &lt;p&gt;//&lt;/p&gt; &lt;p&gt;// Here is sample descriptor that has two top level collection - mouse&amp;nbsp;&lt;/p&gt; &lt;p&gt;// collection and &amp;nbsp;vendor defined collection with a custom feature item. If&amp;nbsp;&lt;/p&gt; &lt;p&gt;// you want to provide sideband communication with your hidmini&amp;nbsp;&lt;/p&gt; &lt;p&gt;// driver, you can add a custom collection with the collection provided&amp;nbsp;&lt;/p&gt; &lt;p&gt;// by the hardware and open the custom collection from an app to&amp;nbsp;&lt;/p&gt; &lt;p&gt;// communicate with the driver.&lt;/p&gt; &lt;p&gt;// 여기 두개의 탑레벨 모음인 샘플 디스크립터가 있다.&lt;/p&gt; &lt;p&gt;// 커스텀 피처아이템을 가진 마우스 모음과 벤더 정의 모음이다.&lt;/p&gt; &lt;p&gt;// 니가 만약 너의 hidmini 드라이버를 가지고 사이드 밴드 통신을 제공하길&lt;/p&gt; &lt;p&gt;// 원한다면, 너는 하드웨어에서 제공되는 모음과 응용프로그램으로부터 드라이버&lt;/p&gt; &lt;p&gt;// 통신하는 것까지 개인모음을 추가할 수 있다.&lt;/p&gt; &lt;p&gt;// (역주: 즉, 몬소리냐면 이거 앞에서 선언한 DefaultReportDescriptor 대신에&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이걸 그냥 가져다가 써라. 마우스 예제다. 이 말이나 마찬가지임.&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;여기에 니가 원하는거 추가해서 쓰라는 소리임. 이미 소스에 다 있었음.)&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; //Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; //Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; //REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; //Usage (Pointer),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; //Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; //Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; //Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; //Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; //Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; //Logical Maximum (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; //Report Count (3),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; //Report Size (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; //Input (Data, Variable, Absolute), ;3 button bits&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; //Report Count (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x05, &amp;nbsp; &amp;nbsp; //Report Size (5),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; //Input (Constant), ;5 bit padding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; //Usage (X),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; //Usage (Y),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x81, &amp;nbsp; &amp;nbsp; //Logical Minimum (-127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x7F, &amp;nbsp; &amp;nbsp; //Logical Maximum (127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; //Report Size (8),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; //Report Count (2),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x06, &amp;nbsp; &amp;nbsp; //input (Data, Variable, Relative), ;2 position bytes (X &amp;amp; Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x06,0x00, 0xFF, &amp;nbsp; // USAGE_PAGE (Vender Defined Usage Page) &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // COLLECTION (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85,0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_ID (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // LOGICAL_MINIMUM(0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x26,0xff, 0x00, &amp;nbsp; // LOGICAL_MAXIMUM(255) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75,0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_SIZE (0x08) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_COUNT (0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xB1,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // FEATURE (Data,Ary,Abs) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// END_COLLECTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자.. 이제 끝났다~ 라고?&lt;/p&gt; &lt;p&gt;한숨을 쉬기에는 너무 이르다. 대부분의 혼선과 문제점은 여기서부터 시작되기 때문이다. Microsoft 사의 WinDDK 라는 개발킷에 있는 vhidmini 샘플은 그저 샘플일 뿐이기에 정상작동이 되는지 확인을 해야하기 때문이다. 필자는 위에서 주석처리 되어있는 마우스 예제 DefaultReportDescriptor 의 주석을 풀고 기존에 있던 샘플 DefaultReportDescriptor 와 교체했다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버를 컴파일하는 방법은 여기서 설명하지 않는다. 그냥 WinDDK 설치후 프로그램 메뉴에서 XP 용 콘솔창을 열고 vhidmini 디렉토리로 이동후 nmake 명령을 내리면 컴파일이 가능한 것을 여기서 구차하게 다 설명을 할순없다. (그러면서도 벌써 설명까지 다 해주는 친절한 금자씨.. ㅎ) 이제 vhidmini 드라이버를 컴파일하고 장치를 인스톨 시키면 오른쪽 화면아래 트레이에 드라이버가 인식되었다고 뜰 것을 기대했다. 우리가 흔히 새 마우스를 USB 포트에 꽂으면 장치가 검색되었다고 뜨는걸 볼 수 있지 않은가? Human Interface Device(휴먼인터페이스장치) 어쩌구라는 메시지와 함께 잠시뒤에 마우스가 발견되었다는 식의 그런 메시지를 기대했다. 그러나 결과는 참담했고 미궁속으로 계속해서 빠져들고 말았다. 왜 그랬을까..? 비단 이 문제는 필자만의 문제가 아니었다. vhidmini 샘플 드라이버를 처음접하는 모든 프로그래머들이 모두 이같은 삽질의 미궁속에 빠져든다는 점을 검색을 통해서 알 수 있었다. 바로, MS 의 함정을 말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 다시 위와 같은 오류를 범해나가는 설명을 할 것이다. 어떤식으로 접근할 것인가와 얼마나 많은 뻘짓이 필요했는가에 대해서 설명할 필요가 있다고 본다. 그로인해서 얻은 것들은 상당히 많이 있다. 바로 단거리 스피드로 달리는 사람들은 놓칠수 있는 정보를 마라토너들은 두루두루 보고 달릴수 있는 것처럼 주변지식들을 충분히 얻을수 있다는 장점이 있다. 이 문서를 쓰는것 자체가 사실 기술적인 것에 너무 치우치는 쪽 보다는 학습방법을 알리는 병행효과를 얻기위한 것이기 때문에 무엇을 보았는지 지금부터 과정을 설명할 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞서서 우리는 가상마우스를 만들기 위해서는 Virtual HID Device 를 만들수 있어야 한다는 점만 인식하고 출발했다. 완전히 지식이 전무한 상태에서 기본 골격코드마져 없는 허당상태로 시작할 수 있는 프로그래머는 아무도 없다. 이미 가상마우스 프로그램을 만들어본 경험이 있는 프로그래머라도 기본적인 코드의 골격없이 모든걸 직접 작성하는걸 기대하는건 어려운일이란 얘기이다. 그래서 우리가 앞에서 선행작업을 한 것이 바로 그 뼈대를 찾기위한 작업이었고, 숱한 오류과정을 거치며 우리가 만들 가상장치의 핵심뼈대를 발굴하고 비교 분석하여 선정하는 작업까지 마쳤다. 그리고 우리가 만들 장치에서 가장 중요한 핵심키포인트를 잡아내는 학습방법까지 소개하였다. 결론적으로 앞에서 습득한 사항들을 요약해 보자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. 우리가 만드는 Virtual HID Device 는 mouse 또는 keyboard 와 혼합형태(혹은 단독일수도.. 그건 선택사항)이며 가상 USB 를 통해서 장치가 인식되어야 한다. 이 점은 프로그래밍적으로 정보를 수집하기 전에 머리속으로 구상한 내용에 속한다.(나중에 언급하겠지만 실제 설치/작동은 프로그래머의 상상과 약간 다르다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;2. 여러 정보들을 수집하여 비교분석 한 뒤 그 중에서 vhidmini 라는 Microsoft 사의 WinDDK 개발킷 공식샘플을 채용하기로 최종결론을 내렸다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;3. vhidmini 라는 샘플을 운용하기위해 요구되는 스킬은 USB 의 HID 라는 인터페이스이며 이 인터페이스의 핵심 키포인트는 바로 Report Descriptor 라는 Descriptor 를 어떻게 기술할 것인가에 달려있다는 점을 알아낼 수 있다. 이 점은 이미 학습방법으로 어떻게 그 특징을 캣치하는지 보여주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;4. 우리는 최종적으로 Virtual HID Device 를 마우스로 인식시키기위해 Report Descriptor 라는 기술자(descriptor)를 찾아내야 했으며 적당한 기술자를 vhidmini.h 에서 발견하였다. 이 기술자를 Default 로 맞추고 컴파일 한 뒤 VMware 에 설치된 윈도우에서 설치하면 실제장치로 인식된다는 것까지 모두 정립하였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;다음의 명령어를 이용해서 장치를 설치할 수 있다. 즉, 윈도우가 설치된 VMware 에는 vhidmini.sys 와 vhidmini.inf 그리고 devcon.exe 라는 총 세개의 파일이 복사되어야 한다. devcon 이라는 툴은 윈도우 장치관리자가 할 수 있는 모든 기능+ 를 콘솔에서 명령내릴수 있도록 해주는 커맨드유틸이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[설치명령]&lt;/p&gt; &lt;p&gt;devcon install vhidmini.inf &amp;quot;{D49F883C-6486-400a-8C22-1A9EF48577E4}\HID_DEVICE&amp;quot; 위와 같이 VMware 에 컴파일된 vhidmini 드라이버 파일들을 모두 복사한 뒤에 설치명령을 내린다. VMware 의 화면에는 신뢰를 받지못한 장치 드라이버 설치시에 뜨는 경고문구가 뜨게될 것이다. &amp;lt;계속&amp;gt; 이라는 버튼을 클릭하게되면 sys 파일을 찾지못해 디렉토리 지정창이 한번 더 뜰 것이다. 그 이유는 현 설치위치(devcon 명령어 실행디렉토리 위치) 밑에 i386 이라는 디렉토리에 sys 파일이 존재한다는 가정을하기 때문이다. 즉, INF 파일이 존재하는 위치를 기준으로 그 하위 i386 디렉토리에서 드라이버파일을 찾는다. 그래서 드라이버를 못찾는다는 창이 뜨게된다. 이건 그냥 적당히 vhidmini.sys 파일이 있는 디렉토리를 지정하면 알아서 설치가된다. 그런데.. 우리가 예상했던 설치모습이 아니었다. 그건 필자만의 착각이었을런지도 모르겠지만, 일단 이렇게 장치의 설치과정은 밍밍하게 끝나버린다. 이제 장치가 제대로 인식되었는지 확인을 하기위해 &amp;quot;장치관리자&amp;quot; 를 오픈한다. 그러면 휴먼인터페이스 장치쪽에 두가지 장치가 새롭게 추가되어있는 것을 보게될 것이다. 그런데, 뭔가 생각하던것과는 다르게 인식된 듯한 생각을 가지게 될 것이다. 그 장치는 그저 Generic HID 장치일 뿐 마우스가 아니다. 이게 도대체 어찌된 영문인가? 뭔가 잘못된 것이 있는지 확인해보고 수도없이 DefaultReportDescriptor 를 수정 해봐도 역시나 마찬가지로 마우스로 인식되질 않았다. Revert to snapshot 을 수도없이 반복하며 디스크립터 (Report Descriptor) 를 수정해도 역시나 반응은 일반장치(Generic HID) 일 뿐이었다. 정확히 말하면 VMware 기준으로 XP 에서 장치를 설치했을때 설치되는 이름은 두가지였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;HID 준수장치&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;quot;Root Enumerated HID Device (sample)&amp;quot;&lt;/p&gt; &lt;p&gt;위의 두가지 장치가 설치된다. 우리가 원하는 것은 &amp;quot;HID 준수장치&amp;quot; 가 &amp;quot;HID 규격 마우스&amp;quot; 로 인식되어야만 한다. 그런데, 이런현상이 계속 지속되어 혼란이 가중될 뿐이었다. 어딘가 필자가 모르는 키포인트가 또다시 존재할 것이리라 생각하고 이 현상을 겪는 어딘가에 있을 동지에게 SOS 를 날려야 했다. 우리의 구글형님이 그러한 고충을 겪는 사람들을 모두 한자리로 집합시켜주었다. 그런데.. 구글이 불러모은 검색정보들은 하나 같이 모두 헛소리들 뿐이었다. 근접은 했어도 정답이 하나도 없는게 아닌가.. 제길.. FireFox 에서 탭을 약 20개 가까이 띄워놓고 검색에 검색을 반복하며 필자의 Report Descriptor 정보중 어디가 잘못되었는지를 찾아내기 위해서 안간힘을 쓰고 있었다. Report Descriptor 라는 것은 무엇인가? USB 라는 장치가 자기의 정보를 상위장치에 넘겨서 인식되도록 하기위한 마치 신분증과도 같은 것이다. 어디서 태어났고 어디서 자랐으며 나이는 몇살이고 남성인지 여성인지 기타등등.. 마치 이런정보처럼 인식정보를 쏘기전에 셋팅하는 값이다. 이 값이 하나라도 잘못될 경우에 장치는 절대로 제대로 인식되지 않는다. 항상 사람이 고생을 하려면 깨닫는 과정에서 착각을 일으키게된다. 필자는 vhidmini.h 파일에 있는 공식적인 마우스(예제) 디스크립터 주석을 풀어서 대체시켰다. 필자는 그 디스크립터를 믿지 못했다. 어딘가 오류가 있거나 한가지를 수정함으로&lt;/p&gt; &lt;p&gt;인해서 다른것까지 수정해야하는 문제점이 걸렸다거나 그런류로 생각할 수 밖에 없었다. 다음은 필자와 같은 문제점을 겪는 사람들에 대한 이야기다. 그다지 위안도 되지 않았고 결국 구글형님을 통해 문제의 정확한 해결점을 찾아낼 수 없었지만.. 그 과정에서 문득 떠오르는 영감을 주었기에 그 과정을 그려보고자 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2007-03/msg00258.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;thank for your advice.&lt;/p&gt; &lt;p&gt;i forget to assign REPORT_ID for each report desc.&lt;/p&gt; &lt;p&gt;It works now.&lt;/p&gt; &lt;p&gt;However, i migrated the corrected report to &amp;quot;hidfake&amp;quot;. (Walter Oney &amp;#39;s sample)&lt;/p&gt; &lt;p&gt;The system pop up 3 &amp;quot;Found New Device Wizard&amp;quot; window and identfy it as &amp;quot;Unknow Device&amp;quot;.&lt;/p&gt; &lt;p&gt;Any difference detween these 2 drivers&amp;#39; enumeration?&lt;/p&gt; &lt;p&gt;Appreciated.&lt;/p&gt; &lt;p&gt;(필자요약: REPORT_ID 를 빼먹었다. 작동된다. 그런데 hidfake 꺼를 배꼈다. 그랬더니 &amp;quot;알려지지않은 장치&amp;quot; 라는 새로운 장치로 &amp;quot;하드웨어 찾기&amp;quot; 가 세개나 뜬다. 나머지는 해석할 필요 없겠다.. 왜 그런가? 라는 질문 이라고 생각하고 넘어간다..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;quot;Doron Holan [MS]&amp;quot; wrote:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; you only need one HID minidriver. from it, a keyboard and a mouse can&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; be&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; enumerated. you just have to put each device into its own top level&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; collection. If you are having trouble, i would find a USB HID that already&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; does this and look at its HID descriptor&lt;/p&gt; &lt;p&gt;(필자요약: 이놈이 다른 게시판에도 있는걸보면 좀 하는거 같다. 대충 번역하면 너는 오직 한개의 HID 미니드라이버만 필요할 뿐이다. 그리고 키보드나 마우스가 열거될수 있는 것으로 부터, 그리고 각각의 그 자신의 탑레벨 모음속에 각장치들을 넣어야만 한다. 만약 문제가 있다면, 니가 만든 USB HID 를 어쩌구 저쩌구.. 뭔가 HID Descriptor 와 연관이 있겠거니하고 그냥 넘어감..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;I&amp;#39;m pretty sure you will need to break up hte device into a Mouse device and Keyboard device. (i.e two drivers,&lt;/p&gt; &lt;p&gt;one with a report descriptor for a keyboard and one for a mouse)&lt;/p&gt; &lt;p&gt;The inf files should not refer to HID\MyVirtualHidDevice - these id&amp;#39;s need to be picked up from keyboard.inf or&lt;/p&gt; &lt;p&gt;msmouse.inf - idealy reporting the compatible id of HID_SYSTEM_KEYBOARD or HID_SYSTEM_MOUSE (i think)&lt;/p&gt; &lt;p&gt;(필자요약: 마우스와 키보드장치속에 hte 장치를 깨야할 필요가 있다라고 해석해야 하나.. &amp;nbsp;이놈이 주장하는 내용은 일단, report descriptor 에 키보드와 마우스가 하나로 일치되어있는가를 확인하라는 내용과 HID\MyVirtual HidDevice 라는 장치명으로 되어있는 vhidmini.sys 샘플이 이름이 잘못되어서 그런게 아니냐는 속임수에 빠지기 쉬운 의견을 제시해 놓고 있다. 마치.. 네이버 지식인인가? 하지만 여기서 얻을 수 있는 점이 있는데 HID_SYSTEM_KEYBOARD, HID_SYSTEM_MOUSE 라는 지시어이다. 어설픈건 혼란을 가중시키는데 원래는 HID_DEVICE_SYSTEM_KEYBOARD 이고 HID_DEVICE_SYSTEM_MOUSE 가 맞는거니까 속지말자. 뒤에서 설명하겠지만 이걸 알아 듣기 위해서 새로운 개념을 습득하게 된다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Hi,&lt;/p&gt; &lt;p&gt;I write a HID minidriver with standard Mouse and Keyboard report&lt;/p&gt; &lt;p&gt;descriptors.&lt;/p&gt; &lt;p&gt;It is based on vhidmini in Windows Server 2003 DDK.&lt;/p&gt; &lt;p&gt;The driver work fine and I can read/write the report from the&lt;/p&gt; &lt;p&gt;device.&lt;/p&gt; &lt;p&gt;The Device Manager shows it is HID-compliant device in HID class,&lt;/p&gt; &lt;p&gt;but&lt;/p&gt; &lt;p&gt;the&lt;/p&gt; &lt;p&gt;Mouse Class and Keyboard Class have none.&lt;/p&gt; &lt;p&gt;How should I do so that it can be a mouse device and keyboard&lt;/p&gt; &lt;p&gt;device?&lt;/p&gt; &lt;p&gt;Should I modify the INF file? My driver&amp;#39;s INF is almost same as the&lt;/p&gt; &lt;p&gt;vhidmini&amp;#39;s.&lt;/p&gt; &lt;p&gt;(필자요약: Windows Server 2003 DDK 로 vhidmini 를 만들었다는 식인데 장치명이 HID-compliant(일반 복합HID 장치)로 인식되는데 마우스 클래스와 키보드 클래스가 없다고 말한다. 어떻게 마우스와 키보드 장치로 인식시키는 것이냐고 물어본다. 자기가 INF 파일을 수정해야 하는지 물어본다. 그리고 INF 파일은 vhidmini 와 거의 같다고 말한다. 이 사람이 겪는 증상이 필자가 겪는 증상과 100% 일치한다. 그런데 불행히도 이 글에는 더이상의 답변이 달려있지 않았다. 눈물의 고배를 마시고 돌아서야 하는 이 저린마음.. T.T 어쩔수 없이 또다시 구글형님의 도움을 받아야한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이 질/답들에서 배운 것은 검증해봐야하는 대상들이다. 일단, HID Report Descriptor 가 잘못되었는지 검증해야하며 INF 파일이 잘못되었는지 검증해봐야하고 &amp;quot;한참을 헤메게 만든 요인이었지만&amp;quot; REPORT ID 에 대해서도 검증해봐야 한다는 몇가지 결론을 얻은채 새로운 검색활로를 모색해보게 된다. 이 검색은 첫 발을 내딘수준에 불과하다. 거의 48시간을 오로지 이 문제를 해결하기 위해서 정보들을 모아야 했다.&lt;/p&gt; &lt;p&gt;http://www.techtalkz.com/microsoft-device-drivers/297875-loading-driver-hid-class.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Loading a driver on HID class&lt;/p&gt; &lt;p&gt;Hi all,&lt;/p&gt; &lt;p&gt;I have a USB device that exposes a HID interface. It is not a mouse or&lt;/p&gt; &lt;p&gt;a keyboard, just a general HID device. Device Manager displays it as a&lt;/p&gt; &lt;p&gt;&amp;quot;HID-compliant device&amp;quot;.&lt;/p&gt; &lt;p&gt;Now I would like to install a device driver on it and use the HID&lt;/p&gt; &lt;p&gt;interface to communicate with.&lt;/p&gt; &lt;p&gt;My INF refers the HID\VID_xxxx&amp;amp;PID_xxxx string and my driver gets&lt;/p&gt; &lt;p&gt;loaded.&lt;/p&gt; &lt;p&gt;So I get the PDO from AddDevice and I need the FileObject to&lt;/p&gt; &lt;p&gt;communicate using IOCTL_HID_SET_FEATURE and IOCTL_HID_GET_FEATURE. But&lt;/p&gt; &lt;p&gt;I cannot retrieve it; I use the FireFly sample and the function&lt;/p&gt; &lt;p&gt;FireflyOpenStack to retrieve the FileObject form the PDO but it fails&lt;/p&gt; &lt;p&gt;in my driver with error 0xC000000E (STATUS_NO_SUCH_DEVICE) when&lt;/p&gt; &lt;p&gt;calling ZwOpenFile.&lt;/p&gt; &lt;p&gt;What&amp;#39;s wrong? The pdoName of the file open by ZwOpenFile is something&lt;/p&gt; &lt;p&gt;like &amp;quot;\Device\00000096&amp;quot;. Is it possible to get the SymbolicLinkName&lt;/p&gt; &lt;p&gt;instead?&lt;/p&gt; &lt;p&gt;If someone could help...&lt;/p&gt; &lt;p&gt;Thanks, Roger&lt;/p&gt; &lt;p&gt;(필자요약: HID 인터페이스를 노출하는 USB 장치를 만들었다. 그런데 그게 마우스나 키보드가 아니네? 단지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;일반 HID 장치인거야. 디바이스 디스플레이에 보면 &amp;quot;HID-compliant device&amp;quot; 라고 표시되네.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;횽님들.. 알려주십쇼.. 뭐 이런 내용식으로 글을 써놨다. 그래도 아는게 많은 사람이라서 그런지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;정보들을 많이 뿌려놨는데 독이되는 요소들이 있지만, 덤으로 알게되는 요소들도 그 못지않게&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;많다. IOCTL_HID_SET_FEATURE 과 IOCTL_HID_GET_FEATURE 에대한 얘기는(추후 구현되어야 하는 내용)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좋은 정보임에 틀림없다. 그런데 우리가 원하는 답을 얻지는 못하고 단지 INF 파일에 VID 와&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PID 스트링이 문제의 시발점이 될수도 있지는 않은가 하는 의심을 해볼수 있다. 물론, 그게 해답은&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;아니지만 추가정보를 검색해야할 키워드로써 대상물망에 넣어두자. VID 란 벤더아이디를 의미하고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;제작사의 고유식별번호이며, PID 란 프로덕트 아이디 즉, 제품번호이겠다. 이게 하드웨어는 모두&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;고유하다고 하는데 과연 이 때문에 마우스나 키보드로 인식이 안되고 일반장치로 인식되는 것일까?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;when are you trying to open a handle? during AddDevice or&lt;/p&gt; &lt;p&gt;IRP_MN_START_DEVICE? neither will work b/c a file create can only occur&lt;/p&gt; &lt;p&gt;once the start irp has come back to the pnp manager. so to make this work i&lt;/p&gt; &lt;p&gt;would&lt;/p&gt; &lt;p&gt;a) register a custom device interface GUID&lt;/p&gt; &lt;p&gt;b) register for device interface arrivals on your custom guid. when you&lt;/p&gt; &lt;p&gt;get called, open your stack like FireFly does&lt;/p&gt; &lt;p&gt;you will also need to register for handle notifications on the file handle&lt;/p&gt; &lt;p&gt;that you open so that you can gracefully disable the device. If you use the&lt;/p&gt; &lt;p&gt;KMDF firefly sample, the WDFIOTARGET object does this for you&lt;/p&gt; &lt;p&gt;(필자요약: 답변중에 하나인데 이 답변은 질문자의 추측보다 더 가관이다. IRP_NM_START_DEVICE 나 AddDevice 등록시 (필자는 커널을 몰라서 몬소린지 모르지만 이건 아니다정도의 감은 있었다.. -_-;) 하라는 식으로 답변이 달려있는데 KMDF 까지 들먹거리는걸로 봐서는 논점에서 많이 빗나갔다. KMDF 는 새로운 드라이버 개발 프레임워크인데 질문자가 그걸 물어본게 아니다. 기존의 방법으로 설명해줘야하는 것이 옳은데 그렇지도 않았고, 너무 많은 작업을 추가하라고 주문하는거보니 필자의 생각과 달랐다. 필자의 감은 Report Descriptor 만으로도 해결될 문제라고 속삭이고 있었기 때문에 이 답은 해결책이 아니었다. 다른 답변중에는 URB 를 보내라는 말도 있었다. 모두 무시한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;지금 거론하는 필자의 문제해결 방법은 링크를 보여주면서 찾아나가는 방법을 설명하고 있다. 그렇기에 링크역시 필자가 검색해서 누른 순서대로 임을 밝힌다. 다음으로 찾은 것은 MSDN 의 설명이다. 그런데 MSDN 의 설명은 항상 깨달음을 얻은뒤에나 값진 보물이 되지 깨달음을 얻기전까지는 그저 잘 만들어진 명세서에 불과하다고 느낄때가 많다. 마치 선생님이 &amp;quot;공부하라&amp;quot;고 그렇게 들볶던 말들이 성인이 된 뒤에 &amp;quot;정답&amp;quot; 이라고 느끼는 것처럼 느낀뒤에만 알 수 있는 것들이 기록되어 있는게 MSDN 과도 같다. 왜 그땐 몰랐지? 왜 그땐 안봤지? 나중에 이런말 자주하게 될거다. ㅎㅎ 그런데.. 역시.. -_-; 이 링크를 보던 시점(현 글을 쓰는 시점기준으로 하루전)만 해도 이 링크는 그저 도움이 안되었다.&lt;/p&gt; &lt;p&gt;http://msdn.microsoft.com/en-us/library/aa487252.aspx&lt;/p&gt; &lt;p&gt;(필자요약: 설명이 잘 되있다. 읽어보라.. 해결책도 들어있다. 그런데 그냥보면 절대 모른다. 개고생하면 그때는 답이 보이지만 그냥보면 모른다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 이 사이트는 중국사이트인데 읽을수가 없다. 몇가지 좋은 키워드와 코드가 있는데 해결책은 아니고 나중에 마우스나 키보드를 구현할때 참고할 만한 코드가 아주 조금 있을 뿐이었다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 필자가 겪는 문제를 어느정도 일부분은 해결한 것 같기도하고 그렇지 않은거 같기도 한데 희한한&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 삽질을 하고 있었다. Descriptor 를 계속해서 바꿔가면서 테스트하는 것을 물어보고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 마우스와 키보드를 인식시키기 위해서 vhidmini 를 기본베이스로 디스크립터를 조작하는데 설치가&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 안된다는 그런 질문이었다. 질문양이 많아서 짤라붙이기는 못하겠다. 답글을 보자.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Adrian Schlesinger&lt;/p&gt; &lt;p&gt;xxxxxx@baum.ro&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 24 Sep 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 7&lt;/p&gt; &lt;p&gt;RE: Simulate keystrokes&lt;/p&gt; &lt;p&gt;I have detected what was wrong:&lt;/p&gt; &lt;p&gt;1. When adding the report ID item to the keyboard top-level collection, an additional byte should be returned to&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;the system at the beginning of the data, specifying that report ID.&lt;/p&gt; &lt;p&gt;2. Communication from user mode did not work because when cycling through the HID devices,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;in addition to vendor ID, product ID and version, the usage specified for the additional end point should also&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;be matched (with Vendor Usage 1), otherwise you can end up trying to call WriteFile for a handle corresponding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;to the keyboard end point.&lt;/p&gt; &lt;p&gt;(필자요약: 질문자의 답글인데 키보드 top-level collection(최상위 모음) 에 REPORT ID 를 추가할때 어쩌구 저쩌구 얘기가 나온다. 그리고 usage 라는 말도 나온다. 필자가 원하는 답이 여기에 있을 것이라고 생각하여 엄청난 검색을 통해 알게되었는데 원하는 답은 아니었다. 단지, top-level 의 개념은 중요했다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 앞에서 어떤사람이 한 질문과 똑같은 질문인듯 싶다. 왜 도대체 마우스로 인식이 안되냐.. 이 질문이다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;다음은 중요한 개념중에 하나인 Top-Level Collection 이다.&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Special Top-Level Collections (Reserved for OS use)&lt;/p&gt; &lt;p&gt;Certain HID top-level collections generate a special HID device string. In Windows 2000, Windows XP, and Windows&lt;/p&gt; &lt;p&gt;Server 2003, the top-level collections listed in Table 6 are special cased and each has an additional hardware ID.&lt;/p&gt; &lt;p&gt;Table 6 identifies these collections. The last column identifies the additional string that is added to the hardware&lt;/p&gt; &lt;p&gt;ID list.&lt;/p&gt; &lt;p&gt;Table 6: Special-Cased Top-Level Collections&lt;/p&gt; &lt;p&gt;Device Type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page &amp;nbsp; &amp;nbsp;Usage ID &amp;nbsp; &amp;nbsp; &amp;nbsp; Additional Hardware ID&lt;/p&gt; &lt;p&gt;Pointer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x02 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Joystick &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x04 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&amp;nbsp;&lt;/p&gt; &lt;p&gt;Game pad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;Keyboard &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x06 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;Keypad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x07 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;System Control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer Audio Control &amp;nbsp; &amp;nbsp; 0x0C &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(필자요약: 이게 모냐면 Top-Level Collection 이라 불리우는 입력장치유형이다. 위에서 Usage Page 와 Usage ID 라는 것이 있는데 이게 바로 Report Descriptor 에 있는 항목에 적혀있다. 이걸 어떻게 바꾸느냐에 따라서 가상장치가 마우스가 되느냐, 키보드가 되느냐 아니면 조이스틱이 되느냐를 결정한다. 멋지지 않은가? 물론, 원하는 해답은 아니다. 그러나 필수적으로 개념을 갖고가야 한다. 여기서 중요한게 있다면 입력 장치의 형태가 공유(share)모델이냐 아니면 베타적모델(독점)이냐 이다. 마우스와 키보드는 독점모델이다. 즉, 마우스와 키보드는 장치가 열려있으면 다른 프로그램이 장치를 열어서 쓰고읽는 것이 불가능 하도록 secure 모델로 처리되어있단다. 이때, 이걸 피해가려면 새로운 장치를 동일하게 하나더 만들어서 그 장치와 통신하면 이런 독점모델을 피해갈 수 있단다. MSDN 에 다 나와있다.. 전부 다~ 링크가 있었는데 FireFox 가 깨져서 다 날아가 버리는 바람에 찾을수 없지만 베타적오픈과 공유오픈이 가능한 표시가 위의 Top-Level Collection 에 일일이 나열되어 있는 정보도 찾을 수 있었다. 어쨌거나 중요한건 짚고 넘어가자.. 참고로 잊지는 않았겠지? 가상장치가 일반장치로 인식되서 마우스 장치로 인식시키려고 뻘짓하다가 이런곳까지 당도하게 된거란 점.. 이렇게 정보들을 다양한 방법으로 얻어서 공부하는데도 웹서핑한다고 눈치주는 경우도 있다. x같은 경우지.. 이게 단순히 노는걸로 보여? 입에서 욕나오네.. 갑자기 머리에 히터가 작동되서 한번 지껄여봤습니다. 다시 집중모드로 돌아가봅시다.. ㅋㅋ)Table 13-1 &amp;nbsp; HIDCLASS-Compatible ID for Each Supported Usage지원되는 HIDCLASS 호환 아이디.. HIDCLASS 는 각 장치로 분배를 해주는 역할을 한다고 합니다. 더 자세한건 묻지마삼 다칩니다요.. 전 아는것만 얘기할 뿐임..&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Usage Page &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Usage &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Compatible ID&lt;/p&gt; &lt;p&gt;Generic desktop &amp;nbsp; &amp;nbsp; &amp;nbsp; Pointer or mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_MOUSE&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard or keypad &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_KEYBOARD&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Joystick or game pad &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (Any) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Report Descriptor Header&amp;gt;&lt;/p&gt; &lt;p&gt;앞서서 XBCD 라고 XBOX 조이스틱 에뮬레이션 드라이버에 대해서 말한적이 있습니다.&lt;/p&gt; &lt;p&gt;헤더의 USAGE_PAGE 를 잘 봅시다. 그리고 USAGE 를 봅니다.&lt;/p&gt; &lt;p&gt;// XBCD 예&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;lt;-- 요건 뭐시냐? Table 13-1 입니다욤..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- 위의 Table 6 에 Joystick 의 Usage ID 보입니껑?&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;// vhidmini.h 의 맨마지막 주석이 되어있었던 마우스예제 헤더&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp;DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Generic Desktop), &amp;nbsp; &amp;lt;-- Table 13-1 일반 데스크탑&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- Mouse 임&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- REPORT_ID 꼭 이게 값이 있는지 확인해야함.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID Tool 이라는 놈은 이 값을 빼고 보여줌.(주의!)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Logical Minimum (0),&lt;/p&gt; &lt;p&gt;여기서 Top-Level collection 이 지칭하는 의미는 상위장치입니다. 이런식으로 다중 인터페이스를 구현할 수 있는데 예를들면 마우스와 키보드를 가상장치 하나로 일타쌍피도 만들어낼 수 있습니다. 시중에 파는 키보드 중에 마우스도 있고 USB 포트도 달려있는 키보드들은 이런 다중인터페이스를 만들기위해서는 multiple top-level collection 지정을 해줘야 한다는 얘기죠. 어쨌거나.. 이러한 정보들은 얻었고 Report Descriptor 가 잘못된 것인가라고 판단해보니 전혀 아니었습니다. 오히려 첫번째 XBCD 의 헤더모습에서는 REPORT ID 가 보이지 않는데 두번째 vhidmini.h 에서는 REPORT ID 항목도 빼먹지않고 넣었고 완벽합니다. 그런데 왜.. 대체 왜!! 인식이 마우스로 되지않고 일반장치라고 잡히는 거냐 이말이죠.. 심지어는 공식사이트에서 다운로드 받은 마우스와 키보드 Report Descriptor 를 가져다가도 해봤고 직접 하드웨어에서 뽑아낸 값을 통해서도 해봤지만 모두 인식이 안되었답니다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;사실.. 위에서 언급한 내용은 탐색과정에서 추가로 얻어내는 개념들에 대해서 비중이 있었기에 설명을 하였습니다. 아마, 계속해서 같은 방식으로 설명하면 이 문서를 보면서 쌍욕을하게 될지도 모르기에 후다닥 빨리 접겠습니다. 다음은 제가 문제해결(일반장치를 마우스로 인식하게 만드는)을 하기 위해서 찾아다녔던 링크입니다. 더 많지만 추려서 올려봅니다.&lt;/p&gt; &lt;p&gt;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&lt;/p&gt; &lt;p&gt;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&lt;/p&gt; &lt;p&gt;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&lt;/p&gt; &lt;p&gt;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(결정적인 영감을 주게된 링크는 바로 다음의 링크이고 사실, 앞에서 한번 언급했었던 링크입니다.. 정확히 말하자면 해결방법을 직설적으로 말해준게 아니라, 넌 이걸 이해해야된다라고만 코드의 일부분을 언급하고 숫가락으로 떠먹여 주지는 않겠다는 인상을 풍기는 답글이지요.. 처음에는 이걸 보고도 잘 이해를 못합니다. 저만 그런건 아닐겁니다. 어떤 질문자 중에서는 프린터, 스캐너, 스마트카드를 비롯해 각종 디바이스 드라이버를 만들었다는 이력을 밝히며 저와 같은 증상때문에 고민을 하고 있는 사람도 있었으니까요.. 제가 볼때 이건 MS 의 함정입니다. 의도하지 않은 함정말입니다.)&lt;/p&gt; &lt;p&gt;https://www.osronline.com/showthread.cfm?link=138652&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;바로 이 답글이 눈을 뜬 사람에게만 통하는 핵심인 셈입니다.&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 22 Jul 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 38&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; .......&lt;/p&gt; &lt;p&gt;(필자요약: 다음의 소스코드와 ReadDescriptorFromRegistry 함수를 봐라.. 너는 이걸 이해해야할 필요가 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 라고 말하며 일부 소스를 첨부했습니다. 그리고는 아무런 추가의 말도 없습니다. 장난하는것도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니고.. -_-; 이때 아차하고 생각을 떠올리면 이 문제는 해결됩니다. 위에서 숱하게 질문하던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 외국 개발자들도 결국에는 알아냈겠지요?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;vhidmini 드라이버를 구동시키고 일반 HID 장치로 인식된 드라이버를 마우스 장치로 둔갑시키기 위해서는&lt;/p&gt; &lt;p&gt;소스를 수정해야 합니다. 바로 vhidmini.c 드라이버 소스를 수정하는 일입니다. 그것도 필자가 생각했었던&lt;/p&gt; &lt;p&gt;Report Descriptor 의 오류를 수정하는 것이 아니라 코드를 수정해야 합니다. 앞에서도 한번 언급했었지만&lt;/p&gt; &lt;p&gt;Microsoft 사의 공식 DDK 샘플소스에 오류가 있을리는 없으니까요. vhidmini.h 에 주석으로 정의되어있던&lt;/p&gt; &lt;p&gt;마우스 Report Descriptor 의 예는 오류가 없었습니다. 오류에 빠지도록 만든것은 바로 ReadDescriptorFromRegistry&lt;/p&gt; &lt;p&gt;함수에 있었습니다. vhidmini 소스를 보면 주석에 써있기를 우리는 하드코딩을 하였다라고 적혀 있습니다.&lt;/p&gt; &lt;p&gt;Report Descriptor 를 하드코딩 하였다는 것이지요. 그런데, 단순히 그냥 하드코딩으로 놔두지.. 더 많은걸&lt;/p&gt; &lt;p&gt;보여주고 싶었던지 if-else 로 두가지 처리루틴으로 나눠놓은것이 문제의 핵심이었던 것입니다. 다음의&lt;/p&gt; &lt;p&gt;소스를 보십시오.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;[vhidmini.c 소스에서 수정해야 할 부분]&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;HID Report Descriptor 를 레지스트리에서 읽어들이는 코드를&lt;/p&gt; &lt;p&gt;&amp;nbsp;하드코딩쪽으만 처리하도록 수정함.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject); &amp;nbsp;// 함정이 발생하는 지역&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 장치를 설치할때 INF 파일에 있는 Report Descriptor 가 레지스트리에 기록되고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분에서 레지스트리에 기록된 Report Descriptor 를 읽어들임.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 그러므로 백날 헤더의 Report Descriptor 를 바꿔봤자 INF 파일에 있었던 것을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 읽어들이는 꼴이 되므로 항상 &amp;quot;일반 HID 장치&amp;quot;(Generic HID Device) 가 드라이버로&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 등록될 수 밖에 없었던 것이다. 이런 제길.. 이 문제로 이틀을 꼬박 다 날렸다니..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Microsoft 는 반성하라~!! Microsoft 는 함정을 제거하라~!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 고로 이 부분으로 빠져들지 않도록 주석처리 하라..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;else{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We will use hard-coded report descriptor.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = DefaultReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Using Hard-coded Report descriptor\n&amp;quot;));&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;case IRP_MN_REMOVE_DEVICE:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // free memory if allocated for report descriptor&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분도 주석처리해야 한다. 왜냐면 레지스트리에서부터 읽어들이지 않았기 때문에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 메모리 할당이 안되어 있기 때문이다. 그냥 두어도 상관없을거 같지만 메모리 해제부분이니&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 꺼림칙하므로 되도록이면 제거하길 바란다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(deviceInfo-&amp;gt;ReadReportDescFromRegistry)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ExFreePool(deviceInfo-&amp;gt;ReportDescriptor);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; SET_NEW_PNP_STATE(deviceInfo, Deleted);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ntStatus = STATUS_SUCCESS; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; break; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이제 vhidmini 샘플을 컴파일하고 VMware 에 vhidmini.sys 와 vhidmini.inf 파일을 복사하자. 그리고 devcon 명령으로 앞서했던 것처럼 install 을 해보자. 설치를 하고나면 장치관리자의 기존에 있던 &amp;quot;HID 준수장치&amp;quot; 라는 것은 없어지고 마우스항목에 &amp;quot;HID 규격 마우스&amp;quot; 가 추가되는 것을 볼 수 있을 것이다.(ㅎㅎ 이맛을 보려고.. 밤을새고 삽질을..) 이제.. 장치관리자에서 새로 추가된 &amp;quot;HID 규격 마우스&amp;quot; 를 선택한 뒤에 속성을 보자. 속성을 선택한 뒤 &amp;quot;자세히&amp;quot; 라는 것을 클릭한다. 그리고 장치인스턴스 ID 라는 것을 보라. HID\MyVirtualHidDevice&amp;amp;Col01 라고 되어있는 것을 볼 수 있다. 또한, 일치하는 장치 ID 를 선택하면 hid_device_system_mouse 라고 되어있다. 즉, 마우스로 인식이 되었다는 것이다. 가상 HID 디바이스 위에서 마우스 장치가 인식되어 있는 것이다. 이제 가상 HID 디바이스와 어플리케이션 간에 통신루틴을 프로그래밍하고 어플리케이션의 명령에따라 상위 클래스로 IRP/URB 같은 요청을 (이거참.. 이 레이어에서는 어떤 요청을 사용해야하는 건지 또 공부해야하는군.. -_-; USB 강의 문서에 보면 상위 클래스는 URB 통신을 한다고 나와있었다..) 날려주면 키보드나 마우스 같은 장치들을 에뮬레이션 시킬수 있다. 곧, 가상장치를 조종할 수 있다. 하지만? 그리 쉽지는 않을 것이다. vhidmini 샘플에는 testvhid 라는 어플리케이션 소스도 같이 들어있는데 이 testvhid 소스는 어플리케이션단에서 vhid miniport 드라이버와 통신하는 예제이다. 참고로 아무런 수정없이 샘플만 컴파일해도 어플리케이션과 드라이버 사이에 제대로 통신이 이루어지지않는다. 역시나 이 문제는 HID Report Descriptor 의 데이타의 구성문제에 속한다. 한번 고생한 것이 또다시 반복되는 시점이기도 하다. 이 부분을 해결하면 어플리케이션은 2 또는 3 가지의 top-level collection 중에서 사용자정의(User-Defined) 콜렉션을 통해서 miniport 드라이버와 통신을 할 수 있게되고 이 통신에 따라서 마우스 IRP 를 상위 클래스로 때려주면 된다. 더 자세한 내용은 스스로 연구하길 바란다. 이상으로 이번문서를 마무리하려고 한다. 왜냐면 이제 테스트 기반이 마련되었으니 나머지 추가구현은 스스로가 해야할 몫이기 때문이다. 어떠한 목적으로 개발하던간에 그 이상은 이제 필자가 관여할 부분이 아닌것 같다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어차피 이 문서의 목적은 가상 마우스를 제작하는 것을 중점으로 삶는 것보다도 모르는 분야를 독학하며 개척해 나갈때 자신의 공부스타일의 한 예로써 제시하는 것이었다. 여기서 거론된 공부스타일을 종합해 본다면 이렇게 말할 수 있을것 같다. &amp;quot;관례를 찾아냄으로써 DIFF 를 추출해내는 공부법&amp;quot; 이라고 할 수 있다. 즉, 최대한 많은 자료들을 검색으로 긁어모은 뒤에 분리분석 작업을 통하여 동일한 부분의 반복을 찾아낸다. 찾아낸 반복내용이 있다면 결국 그 반복은 해당 프로그래밍의 관례에 속한다. 즉, 해당 관례는 몸으로 빨아들이고 차이가 나는 지점에서 기술을 흡수한다. 이런식의 반복학습을 통하여 더이상 다른 코드나 정보들을 찾아낼 수 없다고 판단이 들때 그 기술은 자기것이 된다. 필자는 유저레벨을 공부할때 항상 이방식을 택해왔다. 정보가 고갈되고 더이상 찾아낼수 없을때까지 긴시간을 할애해서 리서치를 먼저 한다. 그 뒤에 코딩으로 들어간다. 그리고 관례코드를 따른다. 그렇게되면 생전 처음보는 프로그래밍에서도 어느지점은 건드려도 되고 어느지점은 절대 건드려서는 안되는지 쉽게(? 정확히가 맞겠다) 익힐수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제는 커널레벨 공부를시작하면서 이 고통스럽고도 지루한 공부방식을 다시 사용하고자하며 다른 사람에게 조그마한 도움이 되고자 이런 문서를 작성하였다. (같이 게임에 미쳐서 광랩하던 친구가 갑자기 URL 을 려줘서 읽어 보았더니 국가에서 인증한 기술이라는 자랑스런 인증서와 함께 뭔가를 팔고있었다. 보란듯이 대놓고 말이다. 디자인도 쌈빡해서 사고싶게 만드는 그것.. 그게 뭔지는 대충 말안해도 알겠지만.. 이 문서를 빨리 공개해야하겠다는 생각이 들었다. 원래는 문서를 다 작성해놓고도 공개하지않는 방향으로 생각을 굳혔다가 아무래도 생각이 바뀌기 시작하였다. 그 이유는 뒷부분의 부록을 보라..) 아마 이 방식으로 공부하는 사람들이 많겠지만 그렇지 않을수도 있을 것이다. 적어도 이렇게 공부할땐 뼈를 깎듯이 힘들지만 원하고자 하는 지식을 얻으면 그 지식의 깊이가 뼈속으로 스며들 것이다. 필자처럼 어떤 새로운 분야에 공부를 시작하거나 공부하는 방법을 몰라서 물어보려는 사람들이 있다면 이 문서를 읽어보라고 말하고 싶다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;잡설&amp;gt;&lt;/p&gt; &lt;p&gt;필자가 만약에 커널디버깅을 잘 다뤘다면 아마도 쉽게 문제를 해결했을지도 모르겠다. 하지만 필자는 귀차니즘 때문에 커널디버깅을 좋아하지 않았고 결국, 공부도하지 않았다. (요즘들어 먹고 살라니.. 공부중이다.. -_-;) 그런데 필자는 오히려 디버거를 쓰지 않으면 않을수록 프로그램에 대한 이해도는 높아진다고 생각한다. 왜냐면 사람의 머리는 충분히 상황을 시뮬레이션 할 수 있다고 생각하기 때문이다. 에뮬레이션은 불가능하겠지만 시뮬레이션은 가능하다. 그리고 이 작업을 통해서 문제가 발생되는 지점을 캣치할 수 있다고 생각한다. 그렇게 되었을때 남보다 더 느릴지 몰라도 이해도는 훨씬더 깊이있는 굴곡을 생성해낸다고 생각한다. 어쩌면 그렇게 믿고싶은 것일지도 모르겠다. 적어도 자신은 그렇게 소신을 갖고있다. 그렇다고 커널디버깅을 배우는 것을 말리거나 도외시하라는 것은 절대 아니다. 필수적으로 갖고가야할 기술이라는 점에는 변함이 없지만 두가지를 모두 안배하는 것이 스스로에게 좀 더 풍요로운 지식을 가져다 줄 것이라는 점을 인지했으면 좋겠다는 의미이다. &amp;quot;Art of Hooking&amp;quot; 이라는 문서처럼 스스로의 깨달음을 전달하려고 쓴 문서는 아니지만 이 시간에도 같은 문제로 삽질하고있을 그들에게(아직도 정확한 답변을 보지 못한 질문자들이 인터넷에 깔려있음을.. 이미 보여줬다..) 이틀이라는 시간을 좀 더 귀중한 곳에 쓸 수 있도록 해줄 수 있다는 것은 행복한 일이라고 생각한다. 만약 누군가에게 이런 도움을 지속적으로 받을수 있었다면 본인은 솔로여야할 이유가 없었을 것이리라.. (아쉽게도 영어를 못하니 국내만이라도 도움을 받으면 좋을듯 싶다.) 참고로.. 이 문서는 주제를 인지하는 시점부터 해결과정을 도출해내는 모든 전 과정이 거의 실시간으로 쓰여졌다.. 그렇게 해야만이 이 문서의 목적인 &amp;quot;가상마우스&amp;quot; 와 &amp;quot;공부방법론&amp;quot; 두가지를 모두 전달할 수 있다고 판단했기 때문이다. 필자는 누군가 이 문서를 읽고 얻은게 있었다면 그것만으로 행복할 것이다. 하드에 처박혀 쓰레기가 된채 어느날 자신도 모르게 삭제되는 그런 정보가 아니라는 점만으로도 충분히 가치있는 것이니까..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록1: 필자가 생각하는 에뮬레이션과 시뮬레이션의 차이점]&lt;/p&gt; &lt;p&gt;에뮬레이션: 기계의 톱니바뀌처럼 구성요소들의 기능자체들이 모두 동일하게 작동해야 한다. (기능/작동의 동일화)&lt;/p&gt; &lt;p&gt;시뮬레이션: 기능자체를 동일하게 할 필요없이 입/출력되는 수치/값만 동일하면 된다. (수치/데이타의 동일화)&lt;/p&gt; &lt;p&gt;(필자주: 틀렸을 수도 있다. 정확하지않다. 다만, 여태까지 몸으로 와닿는 느낌자체를 말로 풀어써본 것 뿐이다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록2: 시중에 떠도는 물리형 Auto Mouse 탐지법]&lt;/p&gt; &lt;p&gt;먼저, 가상장치에 대한 것부터 언급해보고 물리형으로 넘어가겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;1. 가상장치 탐지방법&amp;gt;&lt;/p&gt; &lt;p&gt;재밌는 사실이 있는데 아는 사람은 알 것이고 모르는 사람은 모를 것이다.&lt;/p&gt; &lt;p&gt;MSPRESS 에 보면 짜가장치(FakeDevice) 탐색법이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;HANDLE CtestDlg::FindFakeDevice()&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; GUID hidguid;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; HidD_GetHidGuid(&amp;amp;hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; CDeviceList devlist(hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; int ndevices = devlist.Initialize();&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; for(int i = 0; i &amp;lt; ndevices; ++i)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HANDLE h = CreateFile(devlist.m_list[i].m_linkname, 0,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FILE_SHARE_READ | FILE_SHARE_WRITE,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(h == INVALID_HANDLE_VALUE)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HIDD_ATTRIBUTES attr = {sizeof(HIDD_ATTRIBUTES)};&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;BOOLEAN okay = HidD_GetAttributes(h, &amp;amp;attr);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CloseHandle(h);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(!okay)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(attr.VendorID != HIDFAKE_VID ||&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; attr.ProductID != HIDFAKE_PID)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return CreateFile(devlist.m_list[i].m_linkname,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GENERIC_READ | GENERIC_WRITE, 0, NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; return INVALID_HANDLE_VALUE;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;위의 짜가장치 탐색법은 골때리게 단순하다. 결국에는 HIDFAKE_VID 와 HIDFAKE_PID 를 체크하는 개념이다. 즉, 제작사(Vendor ID)와 제품번호(Product ID)를 가지고 짜가인지 판별하겠다는 개념이다. 그렇다면 제작사와 제품번호는 속일수 없다고 생각하는가? 커널을 뒤짚어 엎는(Subvert) 판국에 저렇게 단순하게 비교해서는 가상장치를 막을수 없다. 위의코드를 보고 판단을 하길 가상장치는 다 막겠다고 판단한다면 정말 큰일이다. 어처구니 없는 싸움이 키보드보안이래 또 발생할 것이기 때문이다. 위의 코드가 의미하는 바를 잘못해석하면 안된다. 위의 코드는 이렇게 해석해야 한다. 그 어떠한 가상장치를 막을수 있다는 컨셉하에 위의 코드를 만들길 시도한것이 아니라 고정장치를 알아내기위해 만들어진 컨셉이라는 점을 말이다. 단지 정형화 되어있는 즉, 고정되어있는 상태에서는 가능할 수 있겠다. 이해를 돕기위해 예를한가지 들어보자. VMware 같은 가상머신 안에서 작동하는 것인지 정도는 파악할 수 있지 않을까 싶다. 왜냐면 VMware 가 동적으로 제작사와 제품번호를 바꿔야할 까닭이 없지않은가? 다르게 말하면 VMware 가 굳이 자기 제품정보를 굳이 속이거나 변덕스럽게 수시로 바꿔야할 필요가 전혀 없다는 얘기다. 이런경우에는 마치 하드웨어처럼 고정장치로 봐도 무방하다. 고로 VMware 에는 항상 고정된 장치가 있다고 판단해도 될 것이며 VMware 안에 구현된 장치들 중에는 가상장치들이 있으므로 항상 디텍트 할 수 있단 얘기가 되므로 위의 짜가장치 탐색법은 그러한 경우에 사용할 수 있는 컨셉이라는 소리다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아직 더 깊이 연구해보지는 않았지만 가상장치와 전쟁을 선포할 경우에 또 하나의 &amp;quot;키보드보안&amp;quot; 같은 파국으로 치닫기에 좋은 스토리가 탄생할 것이다. 차라리 이것을 좀 더 유용한 곳에 사용해보면 어떨까? 바로!! 물리형 Auto Mouse 를 탐지하는 것이다. 기술은 적합한 곳에 쓰라고 있는 것이지 말도안되는 헛다리 싸움에 쓰라고 존재하지 않는다. 기술을 적용시킬때는 단순히 눈과 머리로만 판단하지말고 포괄적인 정황을 바탕으로 자신의 가슴속에 확신이 설때 비로소 본격적인 전쟁에 들어가야 한다. 그저 돈이된다고 키보드보안처럼 너도나도 발담궈놓고 아무도 책임지지않고 아무도 발도 못빼는 승자없는 싸움에 휘말리기 싫다면 필히 이 말을 웃어넘기지 말아야 할 것이다.(아마, 이젠 더이상 발을 빼지도 못할것이다.. 담구지 말라고 뜯어말려도&lt;/p&gt; &lt;p&gt;담궜으니 해야할 일은 그저 땜빵밖에 뭐가 더 있겠는가.. ㅉㅉ)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;2. 물리형 Auto Mouse 탐지&amp;gt;&lt;/p&gt; &lt;p&gt;물리형 Auto Mouse 를 탐지하는 것의 기본바탕은 앞서 짜가장치 탐색에 사용된 코드를 그대로 채용하면 되겠다. 단, 제작사와 제품번호만이 아닌 추가정보를 이용할 필요가 있겠다. 그런데, 왜 효용성이 물리형 Auto Mouse 를 탐지하는 것에 효력이 있을까? 그 이유는 간단하다. 다음과 같은 정보를 보자. 필자는 최근에 오픈된 MMORPG 온라인 게임의 Auto Mouse 를 구매해보았다. 과연 어떻게 돌아가는지 궁금증도 있었고 진짜 완벽하게 구동이 되는것인지 두눈으로 확인해보고 싶었기 때문이었다. 그런데 일단, 한군데의 제품은 구동이 제대로 안되는 것을 확인하였다. 다만, 마우스 입력이나 키보드 입력은 그대로 게임속으로 전달되고 있다는 점에 주목하였다. 과연 그러한 것을 어떻게 탐지해낼 수 있을까? 다음은 USB View 라는 프로그램으로 Auto Mouse 장치의 Descriptor 를 본 화면이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Auto Mouse HID Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;quot;USB Composite 장치&amp;quot;&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x0200&lt;/p&gt; &lt;p&gt;bDeviceClass: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x20 (32)&lt;/p&gt; &lt;p&gt;idVendor: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x03EB (Atmel Corporation)&lt;/p&gt; &lt;p&gt;idProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x4743&lt;/p&gt; &lt;p&gt;bcdDevice: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x1000&lt;/p&gt; &lt;p&gt;iManufacturer: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY&amp;quot;&lt;/p&gt; &lt;p&gt;iProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x02&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY PRO8&amp;quot;&lt;/p&gt; &lt;p&gt;iSerialNumber: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x03&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;1.0.0&amp;quot;&lt;/p&gt; &lt;p&gt;bNumConfigurations: &amp;nbsp; 0x01&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;그렇다. idVendor 가 제작사이고 idProduct 가 제품번호이겠다. 이 정보는 필자가 예상컨대 고정이라 할 수 있다. 일단, 텍스트를 주의깊게 보자. &amp;quot;Atmel Corporation&amp;quot; 이 보이는가? 해커들이 가장 많이 사용한다는 그 유명한 &amp;quot;Atmel&amp;quot; 칩이 사용되었다. 일명 FPGA 칩이라고 불리운다. 이 FPGA 칩은 프로그래밍 가능한 이점이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(사견: 언제부터 마우스가 Atmel 칩으로 제작되었던가? 그래서 오토마우스가 그리도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;비싼거였나보다.. 싸구려 PIC 칩만으로도 마우스를 만들수 있다. 전자업계는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;원래 원가전쟁을 벌이는 계통이라서 단 1원이라도 원가를 절감해 보려고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;깎고깎고 전쟁을 벌인다. 필자의 친구가 전자회사 CEO 라서 이점은 매우 잘&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;알고있다. 그 친구의 말을 빌어보자면 진짜 1원갖고 쪼잔하게 굴 수 밖에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;없다고 한다. 살아남아야 하니까 말이다.. 그런데 FPGA 칩을 쓰는 것을 보면&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좀 수상하다. 왜 재프로그래밍이 가능한 칩을 쓰는 것인가.. 재수없으면 기타장치&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;메모리스틱 리더기같은 것들이 연결되어 있을수도 있으므로 함부로 판단하기는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이르지만 아마도 대량유통되는 칩이 아닌 DIY(사제품)칩을 쓴다는 것은 기정&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;사실이라고 추측할만 하지않은가? 필자가 대에충 찾아보니 Auto Mouse 제작사&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;두군데가 Atmel 칩을 사용하고 있었다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;만약 이 Atmel 칩이 필자가 아는 것과 달리 재프로그래밍이 가능한 기능이 없다면 게임업계에서는 대박의 찬스를 잡은 것이리라.. 왜? 고정이잖은가? 고정!! 또, 재미난 정보를 볼 수 있는데 바로 그 유명하다고 하는 &amp;quot;ATPLAY&amp;quot; 라는 마크가 찍혀있다. 아주 그냥 상호를 갖다가 박아놓은거보니 장사할 생가이 없다하겠다.&lt;/p&gt; &lt;p&gt;일단, 칩이 Atmel 칩으로 제작되어있는 USB 형 물리장치들을 사용하는 사용자는 모두 감시대상순위로 집어넣어도 십중팔구는 맞아떨어질 것이다. 특히나 Atmel 칩에 상관없이 상호명 ATPLAY 가 박혀있다면 그 사용자는 거의 Auto Mouse 를 사용하고 있을 확률이 99.9% 라고 할 수 있겠다. 그리고 USB View 같은 프로그램이 사용하는 루틴들은 위에서 언급된 루틴들에서 크게 벗어나지는 않을테니 쉽게탐지할 수 있다고 감히 추측해본다. 딱한가지 우려되는 사항이 있다면 프로그래밍 가능한 칩이기 때문에 업데이트 기능으로&lt;/p&gt; &lt;p&gt;펌웨어를 갈아치울 경우에 난감하게 될 것이다. 하지만 방금 언급한 방식을 사용한다면 Auto Mouse 제작사의 미래고객이 아닌 현재 고객들은 99.9% 가 탐지된다고 봐도 무방할 것이다. 물론, Auto Mouse 의 종류별로 이짓을 해야겠지만.. 프로그래머들의 습성상 모두 식별자를 기록해놓았을테니(아마, Atmel 칩에 코딩을 의뢰하거나 혹은 Atmel 칩에 프로그램이 가능한 사람을 영입했겠지만 프로그래머들이 그런거 생각안한다. 왜냐면 원리원칙을 따르려는 프로그래머의 심리상 바보같이 위에처럼 ATPLAY 를 박는게 미덕으로&lt;/p&gt; &lt;p&gt;생각할 것이기 때문이다.) 행동만 빨리 취한다면 현재 Auto Mouse 사용자들의 태반은 모두 다 탐지해낼 수 있을 것이라고 감히 판단해본다. 즉, 물리형은 고정이라는 변수를 잘 활용할 수 있기에 탐지도 비교적 수월한 편에 속한다는 것이다. 한가지 더 재미난 상상을 해보자.. 과연 Auto Mouse 업체에서 펌웨어 업데이트 기능을 추가로 만들어내는데 얼마나 시간이 걸릴까? 누가 더 대응이 빠를까..? 과연 이 전쟁에서 Auto Mouse 업체의 대응이 빠를까? 아니면 막는자의 대응이 더 빠를까? 아마도 덩치가 작은쪽이 더 빠르겠지만 두고볼 일일 것이다. 이 전쟁은 어느한쪽의 시간전쟁일 뿐이다.. 정확하고 빠른판단이 내려지면 그대로 바로 행하는 쪽이 이기는 것이다. 현재로써 본 필자의 생각으로는 물리형 Auto Mouse 는 막을 수 있다. 이 문서가 나온 시점 앞으로가 문제이다.. 점차 Auto Mouse 는 가상마우스로 진화를 꿈꾸고 있기 때문이다. 그것이 바로 기술의 대세인 것이다. 오늘의 기술이 내일의 쓰레기가 되어버리는 시대에서 속도전의 중요함이다. 승자는 과연 누가 될까? 아무도 모른다.. 기술은 끝이 없으니까.. 마이 골치아픈 것이다.. -_-; 어디까지나.. 필자 개인이 현 상태를 진단해본 사견일 뿐이다. 이 이상 어케 더 판단하랴..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[HID Descriptor Tool]&lt;/p&gt; &lt;p&gt;USB.ORG 공식 사이트에서 받을수 있음&lt;/p&gt; &lt;p&gt;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&lt;/p&gt; &lt;p&gt;(위에서 언급한 사이트 이외 참고한 사이트)&lt;/p&gt; &lt;p&gt;http://kkamagui.tistory.com/485&lt;/p&gt; &lt;p&gt;http://www.keil.com/forum/docs/thread13037.asp&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_DEVICE_ATTRIBUTES DeviceAttributes = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; sizeof(HID_DEVICE_ATTRIBUTES), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VENDOR_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PRODUCT_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; VERSION_NUMBER &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; };&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같이 HID_REPORT_DEscRIPTOR 라는 것을 볼 수 있는데, 처음에는 이게 뭔지 모른다. 감도 안온다. 그러므로 그 관점을 그대로 두고 다음으로 넘어가서 다른 소스들을 보자. (처음엔 원래 모르겠지.. 나만그런가.. -_-; 제길..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;인터넷에서 검색하면 위의 소스와 MSDN (Microsoft 사의 공식샘플과 설명문서) 을 먼저 보게 될 것이다. 그러면 당연히 vhidmini 라는 것도 접하게 된다. 소스는 인터넷에서 파는 놈들도 있으니 그냥 찾기는 좀 짜증이 날 것이다. Microsoft 사의 홈페이지에서 WinDDK 를 받으라. 그 안에 VHidMini 라는 샘플이 들어있다. 그놈을 보면 다음과 같이 생겨먹은 부분에 주목하자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (NT_SUCCESS(ntStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Use default &amp;quot;HID Descriptor&amp;quot; (hardcoded). We will set the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // wReportLength memeber of HID descriptor when we read the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // the report descriptor either from registry or the hard-coded&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // one.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Microsoft 에서 MSDN 의 설명을 먼저 읽어본 뒤 위의 소스주석부분을 보자. 다음과 같이 친절하게 설명해주고 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;설명에 써있듯이 자기네는 그냥 하드코딩 했으니까 ReadFromRegistry 를 참고하면 다른 디바이스를 등록할 수 있단다. 처음 접할땐 사전지식이 없기에 &amp;quot;이게 뭔 개소리야?&amp;quot; 라고 생각이 들 것이다. (? 반응이 없으면 나만그런거 같다.. ㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다면 이제 개소리는 집어치우고 다음을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--&amp;gt; &amp;nbsp;https://www.osronline.com/showthread.cfm?link=138652&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Radly&lt;/p&gt; &lt;p&gt;xxxxxx@daryllee.com&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This being my first driver project, and an unusual one at that, there&amp;#39;s a lot to get my&lt;/p&gt; &lt;p&gt;head wrapped around. My intent is to produce a virtual HID device (mouse emulation) that&lt;/p&gt; &lt;p&gt;uses a complex non-HID physical device as the input medium. I&amp;#39;m using the VHidMini sample&lt;/p&gt; &lt;p&gt;from the WDK hid folder as a starting point, and I&amp;#39;m now at the point where I need to transform&lt;/p&gt; &lt;p&gt;the sample&amp;#39;s report format into a mouse format. I notice with confusion that the report descriptor&lt;/p&gt; &lt;p&gt;in vhidmini.inf is different from that in vhidmini.h, with no explanation in vhidmini.htm as&lt;/p&gt; &lt;p&gt;to why they are different. Does anyone here have any insight on that?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 놈이 필자가 생각하는 것과 동일한 구현을 해볼려고 삽질중에 무시무시한 고급개발자들과 해커들이 몰린다는 osronline 에 질문을 던져놓고 있다. 이 소리는 무엇인가? 필자도 결국 저 문제에 봉착하게 될 날이 온다는 시나리오를 미리 발견한 것이다. 그러므로 주의 깊게 읽어볼 필요가 있다. 여기서 얻어낼 수 있는 정보는 sample&amp;#39;s report format 이란 것과 report descriptor 라는 두가지 내용이다. 원래부터 찾기힘든 정보들에는 동문서답 내지는 &amp;quot;내가 니 밥처먹는데 밥숫가락으로 퍼먹여주랴?&amp;quot; 정도의 댓글이 달리는데 그래도 이 글의 답글중에 괜찮은 답글이 있다. 근데.. 여전히 찾기힘든 정보만큼이나 짤막하게 달아놓는다. 이런사람이 있다는 것은 희망이고 곧 빛이다. 다음의 답글을 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;입에서 욕은 나온다. 왜? 말할라면 다 말하던가 아니면 동문서답이나 하고 가던가 감칠맛나게 소스 네줄 뿌리고 튀다니.. 그래도 고맙다. 지식을 갈구하는 자에게는 이것조차 선물이다. 제길.. 현자라면 푸념할때가 아닌거 같다. 여기서 뭔가 개념을 잡을 수 있는 정보를 캣치해야만 한다. 이 글에서 외국아가(짱개류 외국애인지 allen zhang 이구나.. 역시 중국은 AUTO 에 강한가보다..) 말하기를 소스코드를 보란다. 그 안에 ReadDescriptorFromRegistry 를 보라고 권하면서 일부 소스를 긁어서 보여준다. 글은 짧지만 분명 소스를 열어봤기에 긁어서 붙여줬을테니 아쉬워도 고마운 행동이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 보라고 한 소스가 바로 위에서 VHidMini 샘플의 일부분이라고 뿌린 부분이다. 즉, 이 부분의 내용은 최초 질문자의 글에서 캣치한 sample&amp;#39;s report format 와 report descriptor 라는 부분에대한 응답이다. 즉, 이 함수의 이름으로부터 알 수 있듯이 레지스트리로부터 디스크립터를 읽어들인다는 것에 바로 Virtual HID Mouse 의 핵심구현이 얽혀있다는 것을 시사한다는 점을 알 수 있다. 그런데 필자도 단지 이두개만 가지고 감을 잡지는 못했다. 왜냐면, 커널을 깊이 공부한 적이 없는 사람이 이 두가지의 자료만을 토대로 감을 잡아낼 수 있겠는가? 그렇다면 그건 천재이거나 영어를 모국어처럼 잘하는 사람일게 분명하다. 필자는 남보다 항상 두배로 삽질을 하는데 머리가 남들보다 딸려서 그렇다. 자료도 항상 두배로 찾아야 한다. 결정적으로 힌트가 되었던 것은 역시 국내사이트인데 드라이버 개발정보를 알려주는 곳인 driveronline.org 에서의 힌트와 임베디드 계통의 KELP 사이트에서 였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://driveronline.org/bbs/view.asp?tb=beusb&amp;amp;GotoPage=1&amp;amp;s_bulu=memo&amp;amp;s_key=pnp&amp;amp;no=1491&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Re] Re] Re] USB 가상 키보드, 마우스 드라이버&lt;/p&gt; &lt;p&gt;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.10.02:10.40 (화)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; Woof&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 605&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;pnp 를 이용해서든지 해서 가상적인 usb 장치가 인식이 되면 일반적인 usb 장치를 다루듯이 이용하시면 됩니다. 일반적으로 실제 장치들은 &amp;nbsp;Windows에서 제공하는 기본적인 드라이버로도 동작하기 때문에 필요가 없지만 이와 같은 경우에는 간단하게 자기 드라이버를 열어서 인식된 장치 device와 통신하는 드라이버 정도는 필요하겠지요. 뭐, usb라서 따로 드라이버없이 application으로도 충분히 가능한건데 다들 위와 같은 방법을 이용하더군요. 새로나온 umdf 등을 이용하면 더 간단하고 새로나온 것에 대한 공부도 하면서 재미나게 할 수 있을지도 모르겠네요. 위 에서 말한 대부분의 경우 라고 한 것의 예를 간단히 들어보면 자신의 드라이버를 올리고 해당 드라이버에서 application과 통신 device를 생성한 뒤에 pnp를 이용해서 가상적인 usb 장치를 만들고 그것과 통신하는 길?을 적당히 만들어서 이용하시면 됩니다. sample에서는 가상적인 장치 인식이 바로 usb나 그런 부분이 아니였던 것 같은데 적당히 고치면 되겠지요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에도 썻지만, 잘 찾으면 다 만들어진 코드 어디 있을 것 같습니다. 저도 한번 찾으려다가 그냥 sample에 있어서 말았는데. :| &amp;nbsp;해당 usb 드라이버를 이용해서&amp;quot; 라는 부분에 대해서 물어보셔서 이 부분만 따로 답을 달면 해당 usb device를 제어(control)하는 드라이버를 지칭했습니다. &amp;nbsp;또 처음에 말한 것 처럼 class관련 드라이버에 대해서는 생각할 필요가 없습니다. 역시 위에 쓴 것 처럼 어디에 쓰실지 궁금하네요. 가상 키입력등은 S/W나 그런 자동화 테스트에 이용하기도 하고 꽤 여러군데서 쓰기는 하는데 안좋지는 않지만 뭐 . 그런데도 쓰여서 :|&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;최초 질문자가 어떻게 구현해야 하냐고 질문하자 pnp 를 통해서 가상적인 usb 를 인식시킨 다음에 적당히 device 와 통신시키라고 한다. 자세한 내용은 말해주지 않고 Microsoft 에서 제공하는 샘플로도 구현이 가능할 것이라는 내용과 어딘가에는 이미 다 만들어진 소스가 있을텐데 찾아보라고 한다. 이말 믿고 인터넷에서 찾아헤메다가는 마누라가 집나가도 모를것이다. 답변에서 보듯이 이 사람은 진짜 적당히 답글을 달고 있는 사람이라는 점을 주의해야 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 사람의 힌트와 통찰력이 Microsoft 사의 샘플에서 존재하는 핵심이라는 점을 알 수 있다. 일단, 정보는 머리속에 꼬깃꼬깃 담아두고 계속 다음 검색으로 넘어가면서 본인의 마음속에 답이 한가지로 수렴되도록 정보들을 계속 얻어 내어보자. 이쯤되면 정상적인 사이트를 뒤지는 것이 힘들어진다. 왜냐면 너무 정보가 부족하기 때문이리라. 고로 컨트롤러를 제어하는 것을 찾아본다. 예를들면 USB HID 조이스틱 드라이버 같은 것을 찾아내는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;다음과 같은 좋은 예가 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.redcl0ud.com/files/XBCD_all_src.cab&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBOX 의 6축 조이스틱 패드를 윈도우에서 사용할 수 있도록 해주는 소스였다. 검색을 할때는 기존에 얻었던 소스에서 일부 특이하게 보일만한 함수를 키워드로 검색하면 운좋게 찾을 수 있다. 소스를 보면 너무 길고 난해하고 이해하기 힘들뿐이다. 당연히 커널관련 지식이 깊지않은 이상 어떻게 분석하고싶어도 그럴 도리가 없다. 그러므로 파일구성을 보는 것이 전부이다. 여기서 또한가지 힌트를 얻을 수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBCD_control.c&lt;/p&gt; &lt;p&gt;XBCD_driver.c&lt;/p&gt; &lt;p&gt;XBCD_driver.h&lt;/p&gt; &lt;p&gt;XBCD_hid.h&lt;/p&gt; &lt;p&gt;XBCD_report.h&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 파일구성에서 driver 나 control 소스를 보기전에 report 라는 눈에 띄는 놈이 있다. 이 헤더파일의 내용을 보게되면 다음과 같은 것이 적혀있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x05, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 5)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x06, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 6)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 9)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0a, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 10)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0b, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 11)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0c, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 12)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Cnst,Ary,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x16, 0x01, 0x80, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (-32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (X)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Simulation Controls)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xba, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Rudder)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xbb, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Throttle)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x39, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Hat switch)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0x3b, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (315)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x65, 0x14, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; UNIT (Eng Rot:Angular Pos)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0d, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 13)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0e, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 14)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 15)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Not Defined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x91, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; OUTPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xc0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // END_COLLECTION&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 이 홈페이지에서 최대한 얻을 수 있는 것은 다 캣치해야 하는 http://www.redcl0ud.com/xbcd.html 홈페이지의 마지막쯤에 보면 http://www.redcl0ud.com/files/USBView.cab 라는 것이 있다. 그리고 캡춰사진이 있는데 핵심사항으로 체크를 해둔 부분이 있다. idVendor, idProduct 라는 부분에 체크를 해두고 있다. 그리고 USBView 에서 보여주는 내용이 모냐면 바로 Device Descriptor 였다. 오호라.. 내친김에 이 사이트에서는 USB 드라이버를 제작하는 방법까지 설명하는 링크를 걸어두고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://euc.jp/periphs/xbox-controller.en.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 링크인데 제목은 &amp;quot;Inside XBox Controller&amp;quot; 라고 되어있다. 대충 무슨내용이 있는지 열거하자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;lt;Inside Xbox Controller&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Overview&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;USB Device Model&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Descriptors&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here are descriptor dumps of the hub, the gamepad and the memory unit.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the integrated hub&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the gamepad (American)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the memory unit&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Vendor/Product IDs&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The vendor ID is 0x045e (Microsoft). Product IDs are as follows:&lt;/p&gt; &lt;p&gt;ID &amp;nbsp; &amp;nbsp;product&lt;/p&gt; &lt;p&gt;0x001c &amp;nbsp; &amp;nbsp;integrated hub&lt;/p&gt; &lt;p&gt;0x0202 &amp;nbsp; &amp;nbsp;gamepad (American)&lt;/p&gt; &lt;p&gt;0x0280 &amp;nbsp; &amp;nbsp;memory unit&lt;/p&gt; &lt;p&gt;0x0284 &amp;nbsp; &amp;nbsp;DVD remote receiver&lt;/p&gt; &lt;p&gt;0x0285 &amp;nbsp; &amp;nbsp;gamepad (Japanese)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;It is not recommended to distinguish Xbox gamepads by vendor/product IDs because third-party controllers may&lt;/p&gt; &lt;p&gt;have their own vendor/product IDs.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Device Class&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;HID Report Format&amp;gt;&lt;/p&gt; &lt;p&gt;Input Report&lt;/p&gt; &lt;p&gt;The input report is 20-byte.&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Output Report&lt;/p&gt; &lt;p&gt;The output report (rumble control) is 6-byte.&amp;nbsp;&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Example of HID Report Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;The Xbox gamepad lacks the HID report descriptor that describes the input/output report formats. Based on the&lt;/p&gt; &lt;p&gt;above report formats I have tried writing the report descriptor for your information. This is a mere example;&lt;/p&gt; &lt;p&gt;neither official nor verified. Accuracy is not guaranteed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Text format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Binary format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * HID Descriptor Tool format (to be loaded into HID Descriptor Tool)&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 내용들이 있었다. 상당히 많은 삘을 주고있다. 누가봐도 HID Descriptor 와 HID Report Format 그리고 Input Report 와 Output Report 를 통해서 통신한다는 아주 기본적인 컨셉(개념)은 머리가 아니라(T.T) 가슴에 와닿을 것이다. (젠쟝.. 가슴에만 담아두마.. -_-;) 일단, 이쯤에서 XBCD 소스는 닫아둔다. 언제 이거 분석하고 앉아있는가.. 최종컨셉이 다르기 때문에 힌트만 뽑아먹고 닫아두는 것이다. 애초에 만들려고 한건 Virtual HID Mouse 인데 이건 그 컨셉이 아니기에 대충 훑어보고 넘겨야 한다. 또 다른 소스들을 보자. 마구잡이로 검색하면서 받아둔 소스중에 앞에서 처음에 말했던 hidmouse 라는 소스를 한번 진단해보자.. -_-;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(PIC 를 이용한 마우스 제작소스)&lt;/p&gt; &lt;p&gt;파일을 열어보니 원하는게 아닌듯 보였는데 알고보니 PIC 용이었다. 운 좋게도 필자는 PIC18x 롬라이터를 갖고 있어서 이 소스가 뭔지 알 수 있었다. 오래전에 친구의 부탁으로 PIC18x 칩에 어셈블리를 롬라이팅 하는 프로그램을 만들어준 적이 있어서 무슨 소스인지 금방 알 수 있었다. 요새는 PIC 프로그래밍에도 C 가 쓰이고 PIC 는 PLC 대체용으로 쓰이기도 한다. 그런데 PIC 로 USB 모듈을 부착하고 마우스로 제작이 가능한거 같았다. 어쨌거나 원하는 내용은 아니었지만 생각해보면 가장 중요한 것이 물리적인 장치 아닌가? 물리적인 장치에서는 기존에 찾은 소스들이나 검색내용들과 어떤 차이가 있는지 알아볼 필요도 있다.&lt;/p&gt; &lt;p&gt;http://www.pudn.com/downloads128/sourcecode/comm/detail543439.html&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 라는 소스에서 파일구성을 보면 특이한 놈이 있다.&lt;/p&gt; &lt;p&gt;usb_descriptors.c 라는 소스가 있는데 여태까지 눈여겨왔던 descriptor 라는 단어가 보일 수 밖에 없다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;/* Device Descriptor */&lt;/p&gt; &lt;p&gt;ROM USB_DEVICE_DEscRIPTOR device_dsc=&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x12, &amp;nbsp; &amp;nbsp;// Size of this descriptor in bytes&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_DEscRIPTOR_DEVICE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// DEVICE descriptor type&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0200, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USB Spec Release Number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Class Code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Subclass code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Protocol code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_EP0_BUFF_SIZE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Max packet size for EP0, see usb_config.h&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Vendor ID&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product ID: Mouse in a circle fw demo&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0003, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device release number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Manufacturer string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device serial number string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Number of possible configurations&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;//Class specific descriptor - HID mouse&lt;/p&gt; &lt;p&gt;ROM struct{BYTE report[HID_RPT01_SIZE];}hid_rpt01={&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {0x05, 0x01, /* Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, /* Usage (Mouse) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, /* Collection (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, /* &amp;nbsp;Usage (Pointer) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, /* &amp;nbsp;Collection (Physical) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Buttons) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Minimum (01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Maximum (03) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (3) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Absolute) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (5) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Constant) &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (X) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (Y) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (-127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (8) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Relative) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, 0xC0}&lt;/p&gt; &lt;p&gt;};/* End Collection,End Collection &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 의 소스는 분석하지 않고 특징적인 몇개의 파일만 열어보고 위의 부분에 주목하고 닫아 버린다. 역시 컨셉은 물리 마우스가 아니라 가상 마우스이기 때문이다. 가상 마우스는 연결되면 오른쪽 아래의 트레이에 연결되었다고 풍선글이 떠야 하는 형태로 진행되어야 하는 것이 머리속의 구상이었다. 이미 driveronline 의 힌트에서 pnp 를 통해서 usb 를 인식시키라는 내용을 보았고 osronline 에서는 vhidmini 의 특정부분을 언급했으며 osronline 의 최초 질문자는 샘플의 포맷과 디스크립터를 언급했다. 다음의 사이트를 보게되면 약 90% 의 감이 오게되는데 임베디드 계통이 역시나 제일 확실하다. 시스템 프로그래머라는 황무지(wild)에서 살아가는 사람들이기 때문이다. 다만, 숫갈로 퍼먹여 주는걸 제일 싫어해서 짜증난다. 다음의 KELP 사이트의 글을 보면(http://kelp.or.kr/korweblog/stories.php?story=07/02/13/3453938)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;글쓴이가 usb mouse 구현시 뭔가 이상하다는 식으로 적어놓고 있는 내용을 볼 수 있는데 한번 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb slave 포트를 이용하여 usb mouse를 구현하고 있습니다.&lt;/p&gt; &lt;p&gt;글쓴이 : omayaro (2007년 02월 13일 오후 02:10) 읽은수: 643&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;커널 2.6.11에서 gadget api를 이용하여 usb 마우스를 구현해 보고 있습니다.&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;처음에 모듈을 등록하기 위하여&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;static int __init my_module_init(void)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;int retval;&lt;/p&gt; &lt;p&gt;retval = usb_gadget_register_driver( &amp;amp;g_ugdDriver );&lt;/p&gt; &lt;p&gt;if (retval)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;printk(KERN_ERR &amp;quot;[ omayaro ] module_init: cannot register gadget driver, ret=%d\n&amp;quot;, retval);&lt;/p&gt; &lt;p&gt;return retval;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;return 0;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에서 처럼 하여 등록을 마쳤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 pc( window xp 와 fedora core4 를 사용하는 pc 2대를 한번씩 테스트 함 )에&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb cable을 연결하였습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그랬더니 임베디드 보드와 pc에 몇가지 반응이 오더군요..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래의 내용은 진짜 마우스를 꼽았을때에 windows xp에서 usb descriptor를&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;분석한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x08 (8)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0000&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x01&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x02&lt;/p&gt; &lt;p&gt;Open Pipes: 1&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Endpoint Descriptor:&lt;/p&gt; &lt;p&gt;bEndpointAddress: 0x81&lt;/p&gt; &lt;p&gt;Transfer Type: Interrupt&lt;/p&gt; &lt;p&gt;wMaxPacketSize: 0x0004 (4)&lt;/p&gt; &lt;p&gt;bInterval: 0x0A&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 아래의 정보는 제가 짠 프로그램이 동작하여 pc에 등록된 정보입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x03&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x10 (16)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0199&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x00&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x00&lt;/p&gt; &lt;p&gt;Open Pipes: 0&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;보시면 ConnectionStatus에 들어 있는 정보가 좀 틀리고 end point의 정보는 아예 없는 것을 보실수 있습니다.. 이 내용을 분석한 제 생각으로는 일단 Open Pipes의 수가 0인 것으로 보아 우선 정상적으로 연결 실패.. 가난 것으로 보이고요 end point가 없는 것으로 보아 어떤 설정또는 ep0를 통하여 세팅중에 에러가 난 것으로 보입니다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 질문...( 서론이 좀 길었죠??ㅡㅜ;;;; ) 제가 아직 usb 에 대해 정확히 이해를 못해서 인지는 몰라도 usb ep0를 통하여 setup이 될때 어떤 순서로 setup이 이루어 지는지 잘 모르겠습니다. 제 생각으로는&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. host가 device descriptor를 요청하여 가져감&lt;/p&gt; &lt;p&gt;2. 나머지 descriptor( configure, interface )를 가져감&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;으로 생각이 되는데요.. 순서가 저렇게 되는 것이 맞나요?? 그리고 pipe( 제 생각에는 in/out end point )가 open되는 시점이 이 언제인지 궁금합니다.. 조금 정리해서 물어본다면.. usb device가 pc에 꽂힌 후 정상 인식 되기까지 host가 device에게 요청하는 메시지의 순서가 궁금하네요~~ 그리고 언제 pipe가 오픈이 되는 지... 도 궁금합니다~~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;고수님들의 답변 기다릴게요~~&lt;/p&gt; &lt;p&gt;하루에 refresh만 5천번하는.. omayaro 였습니다...ㅠ0ㅠ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오케이.. 뭔가 삘이오는데.. 바로 앞에서 가슴속에 담아둔 그거네.. -_-; 중요한건 바로 디스크립터(descriptor) 컨피겨(configure) 인터페이스(interface) 라는 내용이 또 나온다. 어쨌거나 저쨌거나 질문자는 실패한 사람이니까 믿을게 못된다. 여기에 달린 댓글이 중요하다. 그런데.. 역시나.. 멋진 시스템 프로그래머들 같으니라구.. ㅎㅎ 직접읽어보라.. 민망하다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;익명 (2007년 02월 13일 오후 10:08)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 밥은 직접 떠서 드세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; device 연결시점에서는 default(첫번째) configuration 으로 동작합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; host 쪽에서 사용자의 요구에 의해 다른 configuration 으로 전환합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 흔한 경우는 아닙니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 이런 방식을 사용하는 대표적인 경우는 device 쪽에 end point 가 모자랄 경우입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 간혹, host쪽 사용자에게 디버깅 포트등을 숨기기 위해서 사용하기도 합니다.&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;역시나 댓글한번 멋지게 달려있었다. 밥은 직접 떠먹어야 한다는 말. 누가 그걸 모르나. 이쯤되면 검색에 이골이 나기 일보직전이 되고 서서히 자신감도 사라지고 짜증이 섞이기 마련이다. 이때한번 refresh 가 필요한데 검색은 계속되어야 한다.. 쭈~욱.. 점점 검색하다보면 Filter Driver 에 대한 내용이 나오기도 하고 처음부터 검색이 되더라도 알아먹지 못했던 내용이 두번째 검색하다 모르고 똑같은걸 또 보게되면(즉, 본걸 나중에&lt;/p&gt; &lt;p&gt;또 봤을때) 이해가 되기 시작하는 부분이 생겨나기 시작한다. 바로 다음의 부분들이 그러한 부분들이라 하겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;bodnar&lt;/p&gt; &lt;p&gt;February 11th, 2007, 05:58 AM&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am trying to fix a part of the report descriptor on an existing USB HID device that woked fine but&lt;/p&gt; &lt;p&gt;has problems on Vista. It installs&lt;/p&gt; &lt;p&gt;and everything is OK with it but DirectX refuses to see it due to some inconsistency in the report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I understand that I would need to write a filter driver to fix that.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have downloaded recent WDK and looked at the samples, specifically HID\Firefly sample but I cannot figure out&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;how to alter&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Report Descriptor data when the driver receives IRP_MN_START_DEVICE in DispatchPnP. I can see how PDEVICE_OBJECT&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DeviceObject is passed&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;to it but mmm.. how do I get access to HID device details so I can alter it?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;When I look inside HID\Vhidmini virtual HID minidriver I can see exactly what I would want to use in the&lt;/p&gt; &lt;p&gt;filter driver:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am a bit lost... Any help is appreciated.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;미국말로 뭐라 지껄이는지 전혀 관심없다. 오로지 Report Descriptor data when the driver receives IRP_MN_START_DEVICE&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;in DispatchPnP 라는 문장과 다음의 소스 두부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 글에서 필자가 어느타임에 어디를 수정해야 할지 방향을 구체적으로 잡아나갈 수 있는 단초가 마련되기 시작한다. 즉, DispatchPnP 에서 IRP_MN_START_DEVICE 를 받았을때 Report Descriptor data 가 관계가 있다는 점이고 ReportDescriptor 를 NewReportDescriptor 로 할당하는 조작을 잡아낼 수 있다. 원래는 vhidmini 라는 Microsoft 사의 공식샘플이 어떻게 생겨먹었는지&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;잠시 소스 일부분을 보자면&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Store the registry report descriptor in the device extension&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReadReportDescFromRegistry = TRUE;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength =&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(USHORT)RegistryReportDescriptorLength;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위의 모습처럼 되어있다. 그런데 저 미국아가 한 짓은 deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor 를 NewReportDescriptor 로 바꿨다는 것이다. 그러니 필자도 역시 이 부분을 건드리게 될 것이란 소리가 된다. 그러므로 수정을 가할 부분을 한 부분 구체적으로 알아먹었다. 이 글의 맨 처음 시작부분의 Numega Soft 의 소스라고 되어있는 부분을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;해당 부분을 보면 이제서야 뭔가 감이 오기 시작하게 되는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드디어;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.01.28:15.25 (일)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; rechoco&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 &amp;nbsp; &amp;nbsp; 487&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hid minidriver 테스트 살짝 성공~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;샘플소스를 구해서 레포트 디스크립터랑 익스텐션 조금 손만 본거지만.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;디바이스에서 데이터를 hid포멧에 맞춰서 주는게 아니라서..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;강제로 제가 바꿔줘야 했거든요ㅋ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;마우스로 테스트 해봤더니 쭉쭉 잘옮겨지더군요&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;물론 목표한 디지타이져는 아직 안됩니다;;&lt;/p&gt; &lt;p&gt;(와컴것 분석했더니 절대좌표모드일때도, 마우스 플래그를 쓰더군요&lt;/p&gt; &lt;p&gt;xp에서는 디지타이져가 지원이 안되니까 절대좌표 &amp;quot;처럼&amp;quot; 마우스좌표로 작업합니다.&lt;/p&gt; &lt;p&gt;저도 그렇게 하긴했는데. 영 개운하지가 않아서;;&lt;/p&gt; &lt;p&gt;디지타이져가 비스타에서는 지원 된다길래 해봤는데 실패했다는;;)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;제가 참고한 샘플은 WDK의 vhidmini 소스입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;xp용으로 inf파일하고 소스파일 조금 수정하시면 빌드도 잘되고..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헛짓거리중에 잠깐 들러봤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버 온라인님들 모두 화이팅하세요!!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아쉽게도 이 글은 가상 마우스인지 실제 마우스의 필터드라이버를 만든것인지 알길이 없어서 단지 말 그대로 희망만 주는 글인데 되긴 되나부다 정도로만 넘겨야 했다. 중요한 개념가닥을 잡아내는 파편과도 같은 내용들은 모두 끝났고(사실 더 많지만..) 다음의 세가지 정보의 검색이 사실상 전체적인 개념(컨셉)을 모두 얻도록 해주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;1. http://www.eggheadcafe.com/software/aspnet/32296449/virtual-usb-mouse-device.aspx&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual USB Mouse Device only shows as generic HID device. - tomca&amp;gt;&lt;/p&gt; &lt;p&gt;08-May-08 05:16:00&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I wrote a bus driver that generated virtual USB PDO for Printer, Scanner, and&lt;/p&gt; &lt;p&gt;SmartCard. &amp;nbsp;It worked fine before. &amp;nbsp;Recently, I was requested to provide a&lt;/p&gt; &lt;p&gt;virtual USB mouse PDO. &amp;nbsp;What I did was as following steps&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. An usermode application access bus driver to add a new PDO&lt;/p&gt; &lt;p&gt;2. bus driver use IoCreateDeviceSecure to create a new device and invalid&lt;/p&gt; &lt;p&gt;bus relation.&lt;/p&gt; &lt;p&gt;3. PNP manager found this new device, it will query the hardwareid, device&lt;/p&gt; &lt;p&gt;instanceid, and compatible id.&lt;/p&gt; &lt;p&gt;4. I provide USB\Class_03&amp;amp;SubClass_01&amp;amp;Prot_02 as compatible ID&lt;/p&gt; &lt;p&gt;5. System find this is a HID device and start to query Device Descriptor,&lt;/p&gt; &lt;p&gt;Configuration Descriptor, and HID descriptor.&lt;/p&gt; &lt;p&gt;6. Since this is a virtual mouse, bus driver gives HID descriptor without&lt;/p&gt; &lt;p&gt;hardware. &amp;nbsp;I copy a standard mouse device&amp;#39;s HID descriptor (3button usb&lt;/p&gt; &lt;p&gt;mouse) to caller.&lt;/p&gt; &lt;p&gt;7. From Device Manager, I can see a HID device shows up, &amp;nbsp;but there is not&lt;/p&gt; &lt;p&gt;mouse device shows up.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If I plug in a real usb mouse, I can see system create a HID device first,&lt;/p&gt; &lt;p&gt;then HIDClass driver create a PDO for mouhid driver. &amp;nbsp;Is anyting wrong I did?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have carefully checked the USB data sent to caller, everything is ok, but&lt;/p&gt; &lt;p&gt;system doesn&amp;#39;t like this device as mouse, &amp;nbsp;Just consider it as generic USB&lt;/p&gt; &lt;p&gt;HID device.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Could someone give me help?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Thanks!&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;유저모드&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;2. KSP(www.ksyspro.org) 라는 곳에서 작성한 &amp;quot;USB강의자료.PDF&amp;quot; 라는 파일이 인터넷에서 검색되었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;내용의 제목은 &amp;quot;9차 정기 세미나 강의 자료&amp;quot; USB Device Driver 강의였다. 아쉽지만 원래 이런&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;사이트는 문이 닫혀있다. (원래 그런거니까 이해를 해야한다.. -_-; 얼마나 힘들겠는가..? )&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 내용이 작살이다. 이건 그냥 인터넷에서 받아서 보라.. 전체적인 개념정립이 이루어진다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;(아마 앞서서 했던 기본적인 검색뻘짓이 없이는 읽을 수 있는 내용이 아니었으리..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;3. MSDN &amp;amp; ReactOS 소스 중의 USB 부분에 있는 Mouse 드라이버&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 항상 마지막은 MSDN 의 승리이다. 전체적인 모든 내용이 다 들어있다. 빌어먹을 일정수준이상이&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;되지 않으면 처음에 백날봐도 못알아 처먹는다는 것이 문제다. 커널이던 응용프로그래밍이던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이건 차이가 없다. 지금도 응용프로그래밍도 못알아 먹는게 태반이니까. 어쩔수 없이 이 고생을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;치르는건 MSDN 을 보기위해서가 아닐까. (COM 프로그래밍도 MSDN 이 제일 많은 정보가 있다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이 말을 증명해보겠음!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;다음은 MSDN 의 vhidmini.h 라는 파일에 능구렁이처럼 맨 마지막 부분에 주석으로 처리되어있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[vhidmini.h 파일]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;/*&lt;/p&gt; &lt;p&gt;//&lt;/p&gt; &lt;p&gt;// Here is sample descriptor that has two top level collection - mouse&amp;nbsp;&lt;/p&gt; &lt;p&gt;// collection and &amp;nbsp;vendor defined collection with a custom feature item. If&amp;nbsp;&lt;/p&gt; &lt;p&gt;// you want to provide sideband communication with your hidmini&amp;nbsp;&lt;/p&gt; &lt;p&gt;// driver, you can add a custom collection with the collection provided&amp;nbsp;&lt;/p&gt; &lt;p&gt;// by the hardware and open the custom collection from an app to&amp;nbsp;&lt;/p&gt; &lt;p&gt;// communicate with the driver.&lt;/p&gt; &lt;p&gt;// 여기 두개의 탑레벨 모음인 샘플 디스크립터가 있다.&lt;/p&gt; &lt;p&gt;// 커스텀 피처아이템을 가진 마우스 모음과 벤더 정의 모음이다.&lt;/p&gt; &lt;p&gt;// 니가 만약 너의 hidmini 드라이버를 가지고 사이드 밴드 통신을 제공하길&lt;/p&gt; &lt;p&gt;// 원한다면, 너는 하드웨어에서 제공되는 모음과 응용프로그램으로부터 드라이버&lt;/p&gt; &lt;p&gt;// 통신하는 것까지 개인모음을 추가할 수 있다.&lt;/p&gt; &lt;p&gt;// (역주: 즉, 몬소리냐면 이거 앞에서 선언한 DefaultReportDescriptor 대신에&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이걸 그냥 가져다가 써라. 마우스 예제다. 이 말이나 마찬가지임.&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;여기에 니가 원하는거 추가해서 쓰라는 소리임. 이미 소스에 다 있었음.)&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; //Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; //Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; //REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; //Usage (Pointer),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; //Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; //Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; //Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; //Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; //Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; //Logical Maximum (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; //Report Count (3),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; //Report Size (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; //Input (Data, Variable, Absolute), ;3 button bits&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; //Report Count (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x05, &amp;nbsp; &amp;nbsp; //Report Size (5),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; //Input (Constant), ;5 bit padding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; //Usage (X),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; //Usage (Y),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x81, &amp;nbsp; &amp;nbsp; //Logical Minimum (-127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x7F, &amp;nbsp; &amp;nbsp; //Logical Maximum (127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; //Report Size (8),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; //Report Count (2),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x06, &amp;nbsp; &amp;nbsp; //input (Data, Variable, Relative), ;2 position bytes (X &amp;amp; Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x06,0x00, 0xFF, &amp;nbsp; // USAGE_PAGE (Vender Defined Usage Page) &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // COLLECTION (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85,0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_ID (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // LOGICAL_MINIMUM(0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x26,0xff, 0x00, &amp;nbsp; // LOGICAL_MAXIMUM(255) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75,0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_SIZE (0x08) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_COUNT (0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xB1,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // FEATURE (Data,Ary,Abs) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// END_COLLECTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자.. 이제 끝났다~ 라고?&lt;/p&gt; &lt;p&gt;한숨을 쉬기에는 너무 이르다. 대부분의 혼선과 문제점은 여기서부터 시작되기 때문이다. Microsoft 사의 WinDDK 라는 개발킷에 있는 vhidmini 샘플은 그저 샘플일 뿐이기에 정상작동이 되는지 확인을 해야하기 때문이다. 필자는 위에서 주석처리 되어있는 마우스 예제 DefaultReportDescriptor 의 주석을 풀고 기존에 있던 샘플 DefaultReportDescriptor 와 교체했다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버를 컴파일하는 방법은 여기서 설명하지 않는다. 그냥 WinDDK 설치후 프로그램 메뉴에서 XP 용 콘솔창을 열고 vhidmini 디렉토리로 이동후 nmake 명령을 내리면 컴파일이 가능한 것을 여기서 구차하게 다 설명을 할순없다. (그러면서도 벌써 설명까지 다 해주는 친절한 금자씨.. ㅎ) 이제 vhidmini 드라이버를 컴파일하고 장치를 인스톨 시키면 오른쪽 화면아래 트레이에 드라이버가 인식되었다고 뜰 것을 기대했다. 우리가 흔히 새 마우스를 USB 포트에 꽂으면 장치가 검색되었다고 뜨는걸 볼 수 있지 않은가? Human Interface Device(휴먼인터페이스장치) 어쩌구라는 메시지와 함께 잠시뒤에 마우스가 발견되었다는 식의 그런 메시지를 기대했다. 그러나 결과는 참담했고 미궁속으로 계속해서 빠져들고 말았다. 왜 그랬을까..? 비단 이 문제는 필자만의 문제가 아니었다. vhidmini 샘플 드라이버를 처음접하는 모든 프로그래머들이 모두 이같은 삽질의 미궁속에 빠져든다는 점을 검색을 통해서 알 수 있었다. 바로, MS 의 함정을 말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 다시 위와 같은 오류를 범해나가는 설명을 할 것이다. 어떤식으로 접근할 것인가와 얼마나 많은 뻘짓이 필요했는가에 대해서 설명할 필요가 있다고 본다. 그로인해서 얻은 것들은 상당히 많이 있다. 바로 단거리 스피드로 달리는 사람들은 놓칠수 있는 정보를 마라토너들은 두루두루 보고 달릴수 있는 것처럼 주변지식들을 충분히 얻을수 있다는 장점이 있다. 이 문서를 쓰는것 자체가 사실 기술적인 것에 너무 치우치는 쪽 보다는 학습방법을 알리는 병행효과를 얻기위한 것이기 때문에 무엇을 보았는지 지금부터 과정을 설명할 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞서서 우리는 가상마우스를 만들기 위해서는 Virtual HID Device 를 만들수 있어야 한다는 점만 인식하고 출발했다. 완전히 지식이 전무한 상태에서 기본 골격코드마져 없는 허당상태로 시작할 수 있는 프로그래머는 아무도 없다. 이미 가상마우스 프로그램을 만들어본 경험이 있는 프로그래머라도 기본적인 코드의 골격없이 모든걸 직접 작성하는걸 기대하는건 어려운일이란 얘기이다. 그래서 우리가 앞에서 선행작업을 한 것이 바로 그 뼈대를 찾기위한 작업이었고, 숱한 오류과정을 거치며 우리가 만들 가상장치의 핵심뼈대를 발굴하고 비교 분석하여 선정하는 작업까지 마쳤다. 그리고 우리가 만들 장치에서 가장 중요한 핵심키포인트를 잡아내는 학습방법까지 소개하였다. 결론적으로 앞에서 습득한 사항들을 요약해 보자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. 우리가 만드는 Virtual HID Device 는 mouse 또는 keyboard 와 혼합형태(혹은 단독일수도.. 그건 선택사항)이며 가상 USB 를 통해서 장치가 인식되어야 한다. 이 점은 프로그래밍적으로 정보를 수집하기 전에 머리속으로 구상한 내용에 속한다.(나중에 언급하겠지만 실제 설치/작동은 프로그래머의 상상과 약간 다르다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;2. 여러 정보들을 수집하여 비교분석 한 뒤 그 중에서 vhidmini 라는 Microsoft 사의 WinDDK 개발킷 공식샘플을 채용하기로 최종결론을 내렸다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;3. vhidmini 라는 샘플을 운용하기위해 요구되는 스킬은 USB 의 HID 라는 인터페이스이며 이 인터페이스의 핵심 키포인트는 바로 Report Descriptor 라는 Descriptor 를 어떻게 기술할 것인가에 달려있다는 점을 알아낼 수 있다. 이 점은 이미 학습방법으로 어떻게 그 특징을 캣치하는지 보여주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;4. 우리는 최종적으로 Virtual HID Device 를 마우스로 인식시키기위해 Report Descriptor 라는 기술자(descriptor)를 찾아내야 했으며 적당한 기술자를 vhidmini.h 에서 발견하였다. 이 기술자를 Default 로 맞추고 컴파일 한 뒤 VMware 에 설치된 윈도우에서 설치하면 실제장치로 인식된다는 것까지 모두 정립하였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;다음의 명령어를 이용해서 장치를 설치할 수 있다. 즉, 윈도우가 설치된 VMware 에는 vhidmini.sys 와 vhidmini.inf 그리고 devcon.exe 라는 총 세개의 파일이 복사되어야 한다. devcon 이라는 툴은 윈도우 장치관리자가 할 수 있는 모든 기능+ 를 콘솔에서 명령내릴수 있도록 해주는 커맨드유틸이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[설치명령]&lt;/p&gt; &lt;p&gt;devcon install vhidmini.inf &amp;quot;{D49F883C-6486-400a-8C22-1A9EF48577E4}\HID_DEVICE&amp;quot; 위와 같이 VMware 에 컴파일된 vhidmini 드라이버 파일들을 모두 복사한 뒤에 설치명령을 내린다. VMware 의 화면에는 신뢰를 받지못한 장치 드라이버 설치시에 뜨는 경고문구가 뜨게될 것이다. &amp;lt;계속&amp;gt; 이라는 버튼을 클릭하게되면 sys 파일을 찾지못해 디렉토리 지정창이 한번 더 뜰 것이다. 그 이유는 현 설치위치(devcon 명령어 실행디렉토리 위치) 밑에 i386 이라는 디렉토리에 sys 파일이 존재한다는 가정을하기 때문이다. 즉, INF 파일이 존재하는 위치를 기준으로 그 하위 i386 디렉토리에서 드라이버파일을 찾는다. 그래서 드라이버를 못찾는다는 창이 뜨게된다. 이건 그냥 적당히 vhidmini.sys 파일이 있는 디렉토리를 지정하면 알아서 설치가된다. 그런데.. 우리가 예상했던 설치모습이 아니었다. 그건 필자만의 착각이었을런지도 모르겠지만, 일단 이렇게 장치의 설치과정은 밍밍하게 끝나버린다. 이제 장치가 제대로 인식되었는지 확인을 하기위해 &amp;quot;장치관리자&amp;quot; 를 오픈한다. 그러면 휴먼인터페이스 장치쪽에 두가지 장치가 새롭게 추가되어있는 것을 보게될 것이다. 그런데, 뭔가 생각하던것과는 다르게 인식된 듯한 생각을 가지게 될 것이다. 그 장치는 그저 Generic HID 장치일 뿐 마우스가 아니다. 이게 도대체 어찌된 영문인가? 뭔가 잘못된 것이 있는지 확인해보고 수도없이 DefaultReportDescriptor 를 수정 해봐도 역시나 마찬가지로 마우스로 인식되질 않았다. Revert to snapshot 을 수도없이 반복하며 디스크립터 (Report Descriptor) 를 수정해도 역시나 반응은 일반장치(Generic HID) 일 뿐이었다. 정확히 말하면 VMware 기준으로 XP 에서 장치를 설치했을때 설치되는 이름은 두가지였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;HID 준수장치&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;quot;Root Enumerated HID Device (sample)&amp;quot;&lt;/p&gt; &lt;p&gt;위의 두가지 장치가 설치된다. 우리가 원하는 것은 &amp;quot;HID 준수장치&amp;quot; 가 &amp;quot;HID 규격 마우스&amp;quot; 로 인식되어야만 한다. 그런데, 이런현상이 계속 지속되어 혼란이 가중될 뿐이었다. 어딘가 필자가 모르는 키포인트가 또다시 존재할 것이리라 생각하고 이 현상을 겪는 어딘가에 있을 동지에게 SOS 를 날려야 했다. 우리의 구글형님이 그러한 고충을 겪는 사람들을 모두 한자리로 집합시켜주었다. 그런데.. 구글이 불러모은 검색정보들은 하나 같이 모두 헛소리들 뿐이었다. 근접은 했어도 정답이 하나도 없는게 아닌가.. 제길.. FireFox 에서 탭을 약 20개 가까이 띄워놓고 검색에 검색을 반복하며 필자의 Report Descriptor 정보중 어디가 잘못되었는지를 찾아내기 위해서 안간힘을 쓰고 있었다. Report Descriptor 라는 것은 무엇인가? USB 라는 장치가 자기의 정보를 상위장치에 넘겨서 인식되도록 하기위한 마치 신분증과도 같은 것이다. 어디서 태어났고 어디서 자랐으며 나이는 몇살이고 남성인지 여성인지 기타등등.. 마치 이런정보처럼 인식정보를 쏘기전에 셋팅하는 값이다. 이 값이 하나라도 잘못될 경우에 장치는 절대로 제대로 인식되지 않는다. 항상 사람이 고생을 하려면 깨닫는 과정에서 착각을 일으키게된다. 필자는 vhidmini.h 파일에 있는 공식적인 마우스(예제) 디스크립터 주석을 풀어서 대체시켰다. 필자는 그 디스크립터를 믿지 못했다. 어딘가 오류가 있거나 한가지를 수정함으로&lt;/p&gt; &lt;p&gt;인해서 다른것까지 수정해야하는 문제점이 걸렸다거나 그런류로 생각할 수 밖에 없었다. 다음은 필자와 같은 문제점을 겪는 사람들에 대한 이야기다. 그다지 위안도 되지 않았고 결국 구글형님을 통해 문제의 정확한 해결점을 찾아낼 수 없었지만.. 그 과정에서 문득 떠오르는 영감을 주었기에 그 과정을 그려보고자 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2007-03/msg00258.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;thank for your advice.&lt;/p&gt; &lt;p&gt;i forget to assign REPORT_ID for each report desc.&lt;/p&gt; &lt;p&gt;It works now.&lt;/p&gt; &lt;p&gt;However, i migrated the corrected report to &amp;quot;hidfake&amp;quot;. (Walter Oney &amp;#39;s sample)&lt;/p&gt; &lt;p&gt;The system pop up 3 &amp;quot;Found New Device Wizard&amp;quot; window and identfy it as &amp;quot;Unknow Device&amp;quot;.&lt;/p&gt; &lt;p&gt;Any difference detween these 2 drivers&amp;#39; enumeration?&lt;/p&gt; &lt;p&gt;Appreciated.&lt;/p&gt; &lt;p&gt;(필자요약: REPORT_ID 를 빼먹었다. 작동된다. 그런데 hidfake 꺼를 배꼈다. 그랬더니 &amp;quot;알려지지않은 장치&amp;quot; 라는 새로운 장치로 &amp;quot;하드웨어 찾기&amp;quot; 가 세개나 뜬다. 나머지는 해석할 필요 없겠다.. 왜 그런가? 라는 질문 이라고 생각하고 넘어간다..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;quot;Doron Holan [MS]&amp;quot; wrote:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; you only need one HID minidriver. from it, a keyboard and a mouse can&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; be&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; enumerated. you just have to put each device into its own top level&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; collection. If you are having trouble, i would find a USB HID that already&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; does this and look at its HID descriptor&lt;/p&gt; &lt;p&gt;(필자요약: 이놈이 다른 게시판에도 있는걸보면 좀 하는거 같다. 대충 번역하면 너는 오직 한개의 HID 미니드라이버만 필요할 뿐이다. 그리고 키보드나 마우스가 열거될수 있는 것으로 부터, 그리고 각각의 그 자신의 탑레벨 모음속에 각장치들을 넣어야만 한다. 만약 문제가 있다면, 니가 만든 USB HID 를 어쩌구 저쩌구.. 뭔가 HID Descriptor 와 연관이 있겠거니하고 그냥 넘어감..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;I&amp;#39;m pretty sure you will need to break up hte device into a Mouse device and Keyboard device. (i.e two drivers,&lt;/p&gt; &lt;p&gt;one with a report descriptor for a keyboard and one for a mouse)&lt;/p&gt; &lt;p&gt;The inf files should not refer to HID\MyVirtualHidDevice - these id&amp;#39;s need to be picked up from keyboard.inf or&lt;/p&gt; &lt;p&gt;msmouse.inf - idealy reporting the compatible id of HID_SYSTEM_KEYBOARD or HID_SYSTEM_MOUSE (i think)&lt;/p&gt; &lt;p&gt;(필자요약: 마우스와 키보드장치속에 hte 장치를 깨야할 필요가 있다라고 해석해야 하나.. &amp;nbsp;이놈이 주장하는 내용은 일단, report descriptor 에 키보드와 마우스가 하나로 일치되어있는가를 확인하라는 내용과 HID\MyVirtual HidDevice 라는 장치명으로 되어있는 vhidmini.sys 샘플이 이름이 잘못되어서 그런게 아니냐는 속임수에 빠지기 쉬운 의견을 제시해 놓고 있다. 마치.. 네이버 지식인인가? 하지만 여기서 얻을 수 있는 점이 있는데 HID_SYSTEM_KEYBOARD, HID_SYSTEM_MOUSE 라는 지시어이다. 어설픈건 혼란을 가중시키는데 원래는 HID_DEVICE_SYSTEM_KEYBOARD 이고 HID_DEVICE_SYSTEM_MOUSE 가 맞는거니까 속지말자. 뒤에서 설명하겠지만 이걸 알아 듣기 위해서 새로운 개념을 습득하게 된다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Hi,&lt;/p&gt; &lt;p&gt;I write a HID minidriver with standard Mouse and Keyboard report&lt;/p&gt; &lt;p&gt;descriptors.&lt;/p&gt; &lt;p&gt;It is based on vhidmini in Windows Server 2003 DDK.&lt;/p&gt; &lt;p&gt;The driver work fine and I can read/write the report from the&lt;/p&gt; &lt;p&gt;device.&lt;/p&gt; &lt;p&gt;The Device Manager shows it is HID-compliant device in HID class,&lt;/p&gt; &lt;p&gt;but&lt;/p&gt; &lt;p&gt;the&lt;/p&gt; &lt;p&gt;Mouse Class and Keyboard Class have none.&lt;/p&gt; &lt;p&gt;How should I do so that it can be a mouse device and keyboard&lt;/p&gt; &lt;p&gt;device?&lt;/p&gt; &lt;p&gt;Should I modify the INF file? My driver&amp;#39;s INF is almost same as the&lt;/p&gt; &lt;p&gt;vhidmini&amp;#39;s.&lt;/p&gt; &lt;p&gt;(필자요약: Windows Server 2003 DDK 로 vhidmini 를 만들었다는 식인데 장치명이 HID-compliant(일반 복합HID 장치)로 인식되는데 마우스 클래스와 키보드 클래스가 없다고 말한다. 어떻게 마우스와 키보드 장치로 인식시키는 것이냐고 물어본다. 자기가 INF 파일을 수정해야 하는지 물어본다. 그리고 INF 파일은 vhidmini 와 거의 같다고 말한다. 이 사람이 겪는 증상이 필자가 겪는 증상과 100% 일치한다. 그런데 불행히도 이 글에는 더이상의 답변이 달려있지 않았다. 눈물의 고배를 마시고 돌아서야 하는 이 저린마음.. T.T 어쩔수 없이 또다시 구글형님의 도움을 받아야한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이 질/답들에서 배운 것은 검증해봐야하는 대상들이다. 일단, HID Report Descriptor 가 잘못되었는지 검증해야하며 INF 파일이 잘못되었는지 검증해봐야하고 &amp;quot;한참을 헤메게 만든 요인이었지만&amp;quot; REPORT ID 에 대해서도 검증해봐야 한다는 몇가지 결론을 얻은채 새로운 검색활로를 모색해보게 된다. 이 검색은 첫 발을 내딘수준에 불과하다. 거의 48시간을 오로지 이 문제를 해결하기 위해서 정보들을 모아야 했다.&lt;/p&gt; &lt;p&gt;http://www.techtalkz.com/microsoft-device-drivers/297875-loading-driver-hid-class.html&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Loading a driver on HID class&lt;/p&gt; &lt;p&gt;Hi all,&lt;/p&gt; &lt;p&gt;I have a USB device that exposes a HID interface. It is not a mouse or&lt;/p&gt; &lt;p&gt;a keyboard, just a general HID device. Device Manager displays it as a&lt;/p&gt; &lt;p&gt;&amp;quot;HID-compliant device&amp;quot;.&lt;/p&gt; &lt;p&gt;Now I would like to install a device driver on it and use the HID&lt;/p&gt; &lt;p&gt;interface to communicate with.&lt;/p&gt; &lt;p&gt;My INF refers the HID\VID_xxxx&amp;amp;PID_xxxx string and my driver gets&lt;/p&gt; &lt;p&gt;loaded.&lt;/p&gt; &lt;p&gt;So I get the PDO from AddDevice and I need the FileObject to&lt;/p&gt; &lt;p&gt;communicate using IOCTL_HID_SET_FEATURE and IOCTL_HID_GET_FEATURE. But&lt;/p&gt; &lt;p&gt;I cannot retrieve it; I use the FireFly sample and the function&lt;/p&gt; &lt;p&gt;FireflyOpenStack to retrieve the FileObject form the PDO but it fails&lt;/p&gt; &lt;p&gt;in my driver with error 0xC000000E (STATUS_NO_SUCH_DEVICE) when&lt;/p&gt; &lt;p&gt;calling ZwOpenFile.&lt;/p&gt; &lt;p&gt;What&amp;#39;s wrong? The pdoName of the file open by ZwOpenFile is something&lt;/p&gt; &lt;p&gt;like &amp;quot;\Device&lt;/p&gt; &lt;p&gt;본 문서는 파워해커에서 제작되었으며 무단배포를 허용함..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual HID Mouse Driver 연구&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;저자: AmesianX&lt;/p&gt; &lt;p&gt;제작: powerhacker.net&lt;/p&gt; &lt;p&gt;제작년도: 2009년 1월 15일&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[서문]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;본 문서의 시작에 앞서 목적에 대해 언급한다. 이 문서는 두가지 목적을 위해서 작성되어졌다.&lt;/p&gt; &lt;p&gt;첫번째는 모르는 부분에대한 새로운 연구나 공부를 시도할때 참고할 수 있는 공부방식(Style)에 대한 설명이고, 두번째는 Virtual HID Mouse Driver 를 제작할때 참고해야할 전초를 다지기위한 목적으로 구성되어 있다. 이렇게 기술문서를 공개하는 이유에는 여러가지가 있지만 무엇보다 이 기술이라는 분야는 언젠가는 자신이 알고있는 오늘의 기술이 내일의 쓰레기가 된다. 일찌감치 알고있는 정보들은 공개하고 더 높은 곳으로 계속 뛰어오를때 진정으로 아무도 가보지못한 고지에 오른 것이다. 그래야 스스로가 발전하는 길이고 바로 모두가 발전하는 길일 것이다. 고지는 점령 당하라고 있는 것이다. 언제까지 정적인 비공개노선으로 점령당하길 기다리고 있을 것인가? 앞으로는 더욱더 가속화될 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[기술을 습득하는 공부방법]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 새로운 기술을 알고싶다면 최대한 동일기능이 구현된 많은 소스들을 수집하라. 그리고 그 차이점을 소스분석을 통해서 캣치하라. 아마 대부분은 소스분석을 깊게 들어가지 않아도 차이점이 눈에 띄게 될 것이다. 그러나.. 아쉽게도 Virtual HID Mouse 에 대한 소스는 인터넷에서 거의 찾기 힘들 것이다. 물론, 공식적인 샘플들을 찾아낼 수 있지만 필자처럼 커널지식보다 유저레벨 어플리케이션 조작만 파온 사람은 그 유명업체들의 공식샘플을 보고도 감을 잡아내기는 하늘에 별따기처럼 어렵다. 즉, 프로그래밍 = 개념 이라는 공식이 있기 때문에 이 개념만 잡고나면 프로그래밍은 껌씹기나 마찬가지다. 개념을 잡는 요령이 있다면 그것은 바로 앞에서 언급한 동일기능 소스의 차이점을 분석해내는 것이다. 그렇기 때문에 매우 제한된 소스(공식소스들)를 갖고 시작하는 것은 전혀 이해를 이끌어내지 못한다. 최대한 고갈되었다고 생각될 정도로 많은 설명이나 소스들을 검색해서 찾아내야 한다. 이때 사용할 수 있는 방법은 구해낸 소스들의 일부 시그너처(Signature)를 검색키워드로 사용하는 것이다. 이런식으로 최대한 많은 정보들을 뽑다보면 선구자들의 질문들을 찾아낼 수 있다. 바로, 그 질문들에서 핵심개념들을 뽑아낼 수 있다. 자주 언급되는 사항이 바로 그 핵심일 것이다. 어떻게보면 &amp;quot;미네르바&amp;quot; 인지 &amp;quot;미네로하이바&amp;quot; 인지 그 친구처럼 철저한 검색기술로 무장한 채로 짜집기의 달인이 되어야만 할 필요가 있다. 만약 충분히 많이 찾아서 더이상 찾아낼 것 조차 없다고 느끼고 등골이 휘어지는 고통을 여러번 견뎌내었다면 이제 얻어낸 것들을 대상으로 비교분석을 취한다. 그렇게 되면 중요 키포인트가 눈에 보이게 될 것이다. 왜 이렇게 해야 하냐면 답은 간단하다. 스스로 엄청난 고통을 감뇌하면서 충분히 검색을 했는데 다 내용이 거기서 거기인 경우가 99.9% 일 것이다. 왜? 그것은 삽질하는 프로그래머가 택한 프로그래밍 방법론은 달라도 전체적인 흐름은 재밌게도 한가지밖에 없으니까. 이게 답이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;어라? 다 똑같은 소리만 짓거리고 있잖아? 뭔가 좀 더 구체적인 것을 달라고!!&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 소리가 나올때 이미 정답은 구해진 것이나 마찬가지다. 다 똑같은 소리를 짓거린다거나 똑같은 소스에 차이점은 있지만 원하는 것이 아니라고 생각될때 사실상 그것이 원하는 것일 확률이 태반이다. 그 이상의 짜집기(Copy &amp;amp; Paste) 능력은 밥을 숫갈로 퍼서 먹는 것이다. 그런데 필자같은 사람은 퍼서 먹여주는 것을 원한다. 왜? 프로그래밍이 나온 이유가 무엇인가? 로보트를 만들려고 기를 쓰는거보면 모르겠는가? 인간에게 숫갈로 밥을 퍼먹여 주려는게 궁극적인 목적아닌가? 프로그래머는 인간이 아니었나? (하기사 혹자는 로보트&lt;/p&gt; &lt;p&gt;라고도 부릅디다..) 프로그래머는 좀 퍼서 먹여주면 어디가 덧나는가? 짜증나게 약올리는 시스템 프로그래머들이여 퍼먹여주지 않으면 스스로 밥숫갈 놓게되는 날이 온다. 인터넷시대에서 정보라는 것은 물 흐르듯 흐를수 밖에 없기 때문에 빨리 털고 높은 곳으로 뛰지않으면 숫가락 놓을 준비를 해야 할 것이다. 오늘의 신기술이 내일의 쓰레기가 되는 시대에서 서로 돕지않으면 혼자 살아남기 힘들다. 외국애들 보라 오픈소스로 자기의 기술을 다 까발리고 있으면서도 항상 최첨단 기술을 걷고 있는 것을 보면 우리가 얼마나 어리석은지 진정 모르냐 이말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;외국애들은 오픈소스를 통해서 시너지라는 것을 이용하고 있다. 물론, 수 많은 개발자들이 다 참가해서 오픈소스가 완성될 것이라고 착각하면 그건 열라 바보이다. 유명 보안 오픈소스인 Nessus 개발자의 고충이 섞인 글을 읽어보았는가? 오픈소스임에도 불구하고 자기혼자만 개발해 왔다고 써있었다. 대부분의 오픈소스들이 마찬가지라고 보면 될 것이다. 다만, 시너지효과로 인해 개발자 1명이 해낼수 있는 능력이 100명 1000명 수준으로 증폭되었기에 프로젝트가 맥을 이어갈 수 있는 것이다. 즉, 게임용어로 말하면 &amp;quot;버프&amp;quot;(버프를 모르진 않겠지..) 를 받은 것이다. 그렇게 되면 소수의 엘리트 파워가 오픈소스에 집중되는 일반유저의 관심만큼 증폭되기 때문이다. 단순히 눈에보이는게 전부라고 생각한다면 큰 것을 놓치게된다. (아니라고? 아님말고.. 허위사실 유포로 감금되어야 하나.. ㅎㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[현 상황]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현 상황에서는 Virtual HID Mouse 가 Auto Mouse 나 MACRO 라는 시장에서 대안으로 대두된 상태라 x시장에서도 드라이버의 판매가 이루어지고 있는 상황이다. 참고로 이 기술이나 드라이버를 판매자체는 사실 법적인 문제의 소지가 없다. 왜냐면 이 Virtual HID Mouse 기술은 범용기술이기 때문이다. 이 기술이 사용되고있는 쪽은 예를들면 조이스틱을 에뮬레이션하거나(용산에가면 조이스틱 판다..) 블루투스 마우스를 사용하도록 해주거나 혹은 그에 버금가는 마우스 업체들이 주로 보유하고있는 자체기술에서 많이 볼 수 있다. 이건 우리가 늘상 접하는 일반분야에서 말한것 뿐이고 무엇보다 가장 많이 사용되고 있는 곳은 임베디드 산업에서일 것이다. 그러므로 이 기술을 파는 것은 전혀 문제가 될 수 없다. 이 기술자체는 Microsoft 사에서 공식적으로 WinDDK 에 예제와 함께 배포하고 있다는 사실을 알만한 사람들은 이미 다 알고있겠다. 단지 그 이상의 자세한 정보를 찾기가 어렵고 Microsoft 사에서 제공하는 기술정보를 알기위해서 밑받침(선행) 되어야할 정보가 없다는 것이 문제점이다. 그래서 기존에 커널 드라이버를 개발하던 사람들이나 천국이지 필자같은 미천한 어플프로그래머들한테는 짜증만 나게 할 뿐이다. 이 중간에 생략된 정보들이 무엇인지 알아내야 한다. 그것이 유저레벨이라는 미천한 신분에서 커널레벨이라는 귀족신분으로 도약할 수 있는 길이다. 테스트환경 만드는게 짜증나서 공부하지 않았다가 완전 독박 쓴 기분이기에 좀 고약한 말투가 나온다. (기분 상하는 커널레벨의 고급 독자는 당장 이 문서를 접기 바란다. 필자도 커널레벨을 공부해야 윈도우를 진정으로 아는 것이라는 대에 이견이 없다. 다만, 오래전부터 블루스크린과 친구를 맺고싶지 않았을 뿐이다. 이거 참.. 뻘쭘하게 커널과 &amp;quot;절친노트&amp;quot; 라도 찍어야하나..)&lt;/p&gt; &lt;p&gt;===================================================================================================================&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;현재, 인터넷에는 몇몇의 기술 정보이외에는 관련된 기술적 자료를 찾아볼 수 없다고 해도 과언이 아니다. 진짜 짜증나도록 자료가 없다. 이해를 할 수 있을만한 한글로된 기술자료는 극적으로 한개를 찾을 수 있었다. 먼저, Virtual HID Mouse 를 찾아보면 가장먼저 접하게 되는 사이트가 있다. 까마귀라는 한국사람이 자신이 만들었다고하는 Virtual HID Mouse 가 검색이 된다. 블로그의 글 내용인데 사실 저수준을 다루는 고급개발자가 아니면 볼게없다.. (왜? 필자같은 어플프로그래밍 수준은 못알아 먹으니까.. + 안갈켜주니까&lt;/p&gt; &lt;p&gt;-_-;) 그리고 MSDN 이 검색되고 vhidmini 라는 것이 검색된다. 또한, 짱개 사이트의 vhidmouse 라는 소스와 hidmouse 라는 소스도 검색된다. 근데.. 오래전에 GxxxGuard 라는 소스가 인터넷에 떴다는 그 몹쓸 짱개사이트였다. 구현을 하기 위해서는 vhidmini 라는 소스가 그중에서 제일 유력한 후보가 될 것이고 나머지 vhidmouse 와 hidmouse 는 소스를 구하는데 한참이나 걸릴 것이다. 일단, 대충 둘러서 정보를 캣치해야한다. 다음은 이미 다들 알고있겠지만 SoftICE 라는 걸작을 만들어낸 &amp;quot;Numega Soft&amp;quot; 라는 회사의 Virtual HID Mouse 공식샘플의 일부소스이다. 아쉽게도 이 소스는 Windows 9x 계열에서 작동되는 드라이버이므로 NT 계열에서는 사용할 수 없다. 하지만 캣치할 수 있는 중요한 내용이 포함되어 있다. 위에서 언급한 것중에 vhidmouse 라는 것이다. 다음은 vhidmouse 소스 중의 일부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// vmoudev.cpp - &amp;nbsp;virtual mouse device for HID example &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Compuware Corporation &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// NuMega Lab &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// 9 Townsend West &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Nashua, NH 03060 &amp;nbsp;USA &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Copyright (c) 1998 Compuware Corporation. All Rights Reserved. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// Unpublished - rights reserved under the Copyright laws of the &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// United States. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;//============================================================================= &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// This module implements the device class of the virtual HID &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// mouse minidriver. &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;lt;KHID.H&amp;gt; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;vmoudev.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#include &amp;quot;hidmouse.h&amp;quot; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;KTrace T(&amp;quot;&amp;quot;,TRACE_MONITOR, TraceAlways, BreakNever, KUstring(L&amp;quot;HidMouse&amp;quot;)); &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEX 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;#define SCALEY 3 &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, // Logical Maximum (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, // Report Count (3), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, // Report Size (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, // Input (Data, Variable, Absolute), &amp;nbsp; &amp;nbsp;;3 button bits &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, // Report Count (1), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, // Report Size (5), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, // Input (Constant), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, // Usage (X), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, // Usage (Y), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, // Logical Minimum (-127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, // Logical Maximum (127), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, // Report Size (8), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, // Report Count (2), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, // Input (Data, Variable, Relative), &amp;nbsp; &amp;nbsp;;2 position bytes (X &amp;amp; Y) &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; // End Collection, &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// End Collection &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// HardwareID for the virtual mouse. &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR HardwareID[]={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;WCHAR DeviceID[] &amp;nbsp;={L&amp;quot;ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0&amp;quot;}; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_DEVICE_ATTRIBUTES DeviceAttributes = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; sizeof(HID_DEVICE_ATTRIBUTES), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VENDOR_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PRODUCT_ID, &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; VERSION_NUMBER &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; };&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같이 HID_REPORT_DEscRIPTOR 라는 것을 볼 수 있는데, 처음에는 이게 뭔지 모른다. 감도 안온다. 그러므로 그 관점을 그대로 두고 다음으로 넘어가서 다른 소스들을 보자. (처음엔 원래 모르겠지.. 나만그런가.. -_-; 제길..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;인터넷에서 검색하면 위의 소스와 MSDN (Microsoft 사의 공식샘플과 설명문서) 을 먼저 보게 될 것이다. 그러면 당연히 vhidmini 라는 것도 접하게 된다. 소스는 인터넷에서 파는 놈들도 있으니 그냥 찾기는 좀 짜증이 날 것이다. Microsoft 사의 홈페이지에서 WinDDK 를 받으라. 그 안에 VHidMini 라는 샘플이 들어있다. 그놈을 보면 다음과 같이 생겨먹은 부분에 주목하자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (NT_SUCCESS(ntStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Use default &amp;quot;HID Descriptor&amp;quot; (hardcoded). We will set the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // wReportLength memeber of HID descriptor when we read the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // the report descriptor either from registry or the hard-coded&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // one.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Microsoft 에서 MSDN 의 설명을 먼저 읽어본 뒤 위의 소스주석부분을 보자. 다음과 같이 친절하게 설명해주고 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;설명에 써있듯이 자기네는 그냥 하드코딩 했으니까 ReadFromRegistry 를 참고하면 다른 디바이스를 등록할 수 있단다. 처음 접할땐 사전지식이 없기에 &amp;quot;이게 뭔 개소리야?&amp;quot; 라고 생각이 들 것이다. (? 반응이 없으면 나만그런거 같다.. ㅎ)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그렇다면 이제 개소리는 집어치우고 다음을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--&amp;gt; &amp;nbsp;&lt;a href=&quot;https://www.osronline.com/showthread.cfm?link=138652&quot; target=&quot;_blank&quot;&gt;https://www.osronline.com/showthread.cfm?link=138652&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Radly&lt;/p&gt; &lt;p&gt;xxxxxx@daryllee.com&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This being my first driver project, and an unusual one at that, there&amp;#39;s a lot to get my&lt;/p&gt; &lt;p&gt;head wrapped around. My intent is to produce a virtual HID device (mouse emulation) that&lt;/p&gt; &lt;p&gt;uses a complex non-HID physical device as the input medium. I&amp;#39;m using the VHidMini sample&lt;/p&gt; &lt;p&gt;from the WDK hid folder as a starting point, and I&amp;#39;m now at the point where I need to transform&lt;/p&gt; &lt;p&gt;the sample&amp;#39;s report format into a mouse format. I notice with confusion that the report descriptor&lt;/p&gt; &lt;p&gt;in vhidmini.inf is different from that in vhidmini.h, with no explanation in vhidmini.htm as&lt;/p&gt; &lt;p&gt;to why they are different. Does anyone here have any insight on that?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어떤 놈이 필자가 생각하는 것과 동일한 구현을 해볼려고 삽질중에 무시무시한 고급개발자들과 해커들이 몰린다는 osronline 에 질문을 던져놓고 있다. 이 소리는 무엇인가? 필자도 결국 저 문제에 봉착하게 될 날이 온다는 시나리오를 미리 발견한 것이다. 그러므로 주의 깊게 읽어볼 필요가 있다. 여기서 얻어낼 수 있는 정보는 sample&amp;#39;s report format 이란 것과 report descriptor 라는 두가지 내용이다. 원래부터 찾기힘든 정보들에는 동문서답 내지는 &amp;quot;내가 니 밥처먹는데 밥숫가락으로 퍼먹여주랴?&amp;quot; 정도의 댓글이 달리는데 그래도 이 글의 답글중에 괜찮은 답글이 있다. 근데.. 여전히 찾기힘든 정보만큼이나 짤막하게 달아놓는다. 이런사람이 있다는 것은 희망이고 곧 빛이다. 다음의 답글을 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;입에서 욕은 나온다. 왜? 말할라면 다 말하던가 아니면 동문서답이나 하고 가던가 감칠맛나게 소스 네줄 뿌리고 튀다니.. 그래도 고맙다. 지식을 갈구하는 자에게는 이것조차 선물이다. 제길.. 현자라면 푸념할때가 아닌거 같다. 여기서 뭔가 개념을 잡을 수 있는 정보를 캣치해야만 한다. 이 글에서 외국아가(짱개류 외국애인지 allen zhang 이구나.. 역시 중국은 AUTO 에 강한가보다..) 말하기를 소스코드를 보란다. 그 안에 ReadDescriptorFromRegistry 를 보라고 권하면서 일부 소스를 긁어서 보여준다. 글은 짧지만 분명 소스를 열어봤기에 긁어서 붙여줬을테니 아쉬워도 고마운 행동이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 보라고 한 소스가 바로 위에서 VHidMini 샘플의 일부분이라고 뿌린 부분이다. 즉, 이 부분의 내용은 최초 질문자의 글에서 캣치한 sample&amp;#39;s report format 와 report descriptor 라는 부분에대한 응답이다. 즉, 이 함수의 이름으로부터 알 수 있듯이 레지스트리로부터 디스크립터를 읽어들인다는 것에 바로 Virtual HID Mouse 의 핵심구현이 얽혀있다는 것을 시사한다는 점을 알 수 있다. 그런데 필자도 단지 이두개만 가지고 감을 잡지는 못했다. 왜냐면, 커널을 깊이 공부한 적이 없는 사람이 이 두가지의 자료만을 토대로 감을 잡아낼 수 있겠는가? 그렇다면 그건 천재이거나 영어를 모국어처럼 잘하는 사람일게 분명하다. 필자는 남보다 항상 두배로 삽질을 하는데 머리가 남들보다 딸려서 그렇다. 자료도 항상 두배로 찾아야 한다. 결정적으로 힌트가 되었던 것은 역시 국내사이트인데 드라이버 개발정보를 알려주는 곳인 driveronline.org 에서의 힌트와 임베디드 계통의 KELP 사이트에서 였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://driveronline.org/bbs/view.asp?tb=beusb&amp;amp;GotoPage=1&amp;amp;s_bulu=memo&amp;amp;s_key=pnp&amp;amp;no=1491&quot; target=&quot;_blank&quot;&gt;http://driveronline.org/bbs/view.asp?tb=beusb&amp;amp;GotoPage=1&amp;amp;s_bulu=memo&amp;amp;s_key=pnp&amp;amp;no=1491&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Re] Re] Re] USB 가상 키보드, 마우스 드라이버&lt;/p&gt; &lt;p&gt;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.10.02:10.40 (화)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; Woof&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 605&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;pnp 를 이용해서든지 해서 가상적인 usb 장치가 인식이 되면 일반적인 usb 장치를 다루듯이 이용하시면 됩니다. 일반적으로 실제 장치들은 &amp;nbsp;Windows에서 제공하는 기본적인 드라이버로도 동작하기 때문에 필요가 없지만 이와 같은 경우에는 간단하게 자기 드라이버를 열어서 인식된 장치 device와 통신하는 드라이버 정도는 필요하겠지요. 뭐, usb라서 따로 드라이버없이 application으로도 충분히 가능한건데 다들 위와 같은 방법을 이용하더군요. 새로나온 umdf 등을 이용하면 더 간단하고 새로나온 것에 대한 공부도 하면서 재미나게 할 수 있을지도 모르겠네요. 위 에서 말한 대부분의 경우 라고 한 것의 예를 간단히 들어보면 자신의 드라이버를 올리고 해당 드라이버에서 application과 통신 device를 생성한 뒤에 pnp를 이용해서 가상적인 usb 장치를 만들고 그것과 통신하는 길?을 적당히 만들어서 이용하시면 됩니다. sample에서는 가상적인 장치 인식이 바로 usb나 그런 부분이 아니였던 것 같은데 적당히 고치면 되겠지요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에도 썻지만, 잘 찾으면 다 만들어진 코드 어디 있을 것 같습니다. 저도 한번 찾으려다가 그냥 sample에 있어서 말았는데. :| &amp;nbsp;해당 usb 드라이버를 이용해서&amp;quot; 라는 부분에 대해서 물어보셔서 이 부분만 따로 답을 달면 해당 usb device를 제어(control)하는 드라이버를 지칭했습니다. &amp;nbsp;또 처음에 말한 것 처럼 class관련 드라이버에 대해서는 생각할 필요가 없습니다. 역시 위에 쓴 것 처럼 어디에 쓰실지 궁금하네요. 가상 키입력등은 S/W나 그런 자동화 테스트에 이용하기도 하고 꽤 여러군데서 쓰기는 하는데 안좋지는 않지만 뭐 . 그런데도 쓰여서 :|&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;최초 질문자가 어떻게 구현해야 하냐고 질문하자 pnp 를 통해서 가상적인 usb 를 인식시킨 다음에 적당히 device 와 통신시키라고 한다. 자세한 내용은 말해주지 않고 Microsoft 에서 제공하는 샘플로도 구현이 가능할 것이라는 내용과 어딘가에는 이미 다 만들어진 소스가 있을텐데 찾아보라고 한다. 이말 믿고 인터넷에서 찾아헤메다가는 마누라가 집나가도 모를것이다. 답변에서 보듯이 이 사람은 진짜 적당히 답글을 달고 있는 사람이라는 점을 주의해야 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 사람의 힌트와 통찰력이 Microsoft 사의 샘플에서 존재하는 핵심이라는 점을 알 수 있다. 일단, 정보는 머리속에 꼬깃꼬깃 담아두고 계속 다음 검색으로 넘어가면서 본인의 마음속에 답이 한가지로 수렴되도록 정보들을 계속 얻어 내어보자. 이쯤되면 정상적인 사이트를 뒤지는 것이 힘들어진다. 왜냐면 너무 정보가 부족하기 때문이리라. 고로 컨트롤러를 제어하는 것을 찾아본다. 예를들면 USB HID 조이스틱 드라이버 같은 것을 찾아내는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;다음과 같은 좋은 예가 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.redcl0ud.com/files/XBCD_all_src.cab&quot; target=&quot;_blank&quot;&gt;http://www.redcl0ud.com/files/XBCD_all_src.cab&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBOX 의 6축 조이스틱 패드를 윈도우에서 사용할 수 있도록 해주는 소스였다. 검색을 할때는 기존에 얻었던 소스에서 일부 특이하게 보일만한 함수를 키워드로 검색하면 운좋게 찾을 수 있다. 소스를 보면 너무 길고 난해하고 이해하기 힘들뿐이다. 당연히 커널관련 지식이 깊지않은 이상 어떻게 분석하고싶어도 그럴 도리가 없다. 그러므로 파일구성을 보는 것이 전부이다. 여기서 또한가지 힌트를 얻을 수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;XBCD_control.c&lt;/p&gt; &lt;p&gt;XBCD_driver.c&lt;/p&gt; &lt;p&gt;XBCD_driver.h&lt;/p&gt; &lt;p&gt;XBCD_hid.h&lt;/p&gt; &lt;p&gt;XBCD_report.h&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 파일구성에서 driver 나 control 소스를 보기전에 report 라는 눈에 띄는 놈이 있다. 이 헤더파일의 내용을 보게되면 다음과 같은 것이 적혀있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x05, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 5)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x06, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 6)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 9)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0a, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 10)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0b, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 11)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0c, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 12)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Cnst,Ary,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x16, 0x01, 0x80, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (-32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x7f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (32767)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (X)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Simulation Controls)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (2)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xba, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Rudder)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0xbb, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Throttle)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Generic Desktop)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x39, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Hat switch)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x07, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (7)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0x3b, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (315)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x65, 0x14, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; UNIT (Eng Rot:Angular Pos)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (4)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0d, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 13)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0e, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 14)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x0f, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 15)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x10, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Button 16)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; INPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x26, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x46, 0xff, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (255)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_SIZE (8)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; REPORT_COUNT (3)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Not Defined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE (Undefined)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x91, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; OUTPUT (Data,Var,Abs)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xc0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // END_COLLECTION&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 이 홈페이지에서 최대한 얻을 수 있는 것은 다 캣치해야 하는&lt;a href=&quot;http://www.redcl0ud.com/xbcd.html&quot; target=&quot;_blank&quot;&gt;http://www.redcl0ud.com/xbcd.html&lt;/a&gt;&amp;nbsp;홈페이지의 마지막쯤에 보면&lt;a href=&quot;http://www.redcl0ud.com/files/USBView.cab&quot; target=&quot;_blank&quot;&gt;http://www.redcl0ud.com/files/USBView.cab&lt;/a&gt;&amp;nbsp;라는 것이 있다. 그리고 캡춰사진이 있는데 핵심사항으로 체크를 해둔 부분이 있다. idVendor, idProduct 라는 부분에 체크를 해두고 있다. 그리고 USBView 에서 보여주는 내용이 모냐면 바로 Device Descriptor 였다. 오호라.. 내친김에 이 사이트에서는 USB 드라이버를 제작하는 방법까지 설명하는 링크를 걸어두고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://euc.jp/periphs/xbox-controller.en.html&quot; target=&quot;_blank&quot;&gt;http://euc.jp/periphs/xbox-controller.en.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 링크인데 제목은 &amp;quot;Inside XBox Controller&amp;quot; 라고 되어있다. 대충 무슨내용이 있는지 열거하자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;lt;Inside Xbox Controller&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Overview&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;USB Device Model&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Descriptors&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here are descriptor dumps of the hub, the gamepad and the memory unit.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the integrated hub&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the gamepad (American)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Descriptors of the memory unit&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Vendor/Product IDs&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The vendor ID is 0x045e (Microsoft). Product IDs are as follows:&lt;/p&gt; &lt;p&gt;ID &amp;nbsp; &amp;nbsp;product&lt;/p&gt; &lt;p&gt;0x001c &amp;nbsp; &amp;nbsp;integrated hub&lt;/p&gt; &lt;p&gt;0x0202 &amp;nbsp; &amp;nbsp;gamepad (American)&lt;/p&gt; &lt;p&gt;0x0280 &amp;nbsp; &amp;nbsp;memory unit&lt;/p&gt; &lt;p&gt;0x0284 &amp;nbsp; &amp;nbsp;DVD remote receiver&lt;/p&gt; &lt;p&gt;0x0285 &amp;nbsp; &amp;nbsp;gamepad (Japanese)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;It is not recommended to distinguish Xbox gamepads by vendor/product IDs because third-party controllers may&lt;/p&gt; &lt;p&gt;have their own vendor/product IDs.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Device Class&amp;gt;&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;HID Report Format&amp;gt;&lt;/p&gt; &lt;p&gt;Input Report&lt;/p&gt; &lt;p&gt;The input report is 20-byte.&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Output Report&lt;/p&gt; &lt;p&gt;The output report (rumble control) is 6-byte.&amp;nbsp;&lt;/p&gt; &lt;p&gt;헤더그림&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Example of HID Report Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;The Xbox gamepad lacks the HID report descriptor that describes the input/output report formats. Based on the&lt;/p&gt; &lt;p&gt;above report formats I have tried writing the report descriptor for your information. This is a mere example;&lt;/p&gt; &lt;p&gt;neither official nor verified. Accuracy is not guaranteed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Text format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * Binary format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; * HID Descriptor Tool format (to be loaded into HID Descriptor Tool)&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위와 같은 내용들이 있었다. 상당히 많은 삘을 주고있다. 누가봐도 HID Descriptor 와 HID Report Format 그리고 Input Report 와 Output Report 를 통해서 통신한다는 아주 기본적인 컨셉(개념)은 머리가 아니라(T.T) 가슴에 와닿을 것이다. (젠쟝.. 가슴에만 담아두마.. -_-;) 일단, 이쯤에서 XBCD 소스는 닫아둔다. 언제 이거 분석하고 앉아있는가.. 최종컨셉이 다르기 때문에 힌트만 뽑아먹고 닫아두는 것이다. 애초에 만들려고 한건 Virtual HID Mouse 인데 이건 그 컨셉이 아니기에 대충 훑어보고 넘겨야 한다. 또 다른 소스들을 보자. 마구잡이로 검색하면서 받아둔 소스중에 앞에서 처음에 말했던 hidmouse 라는 소스를 한번 진단해보자.. -_-;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(PIC 를 이용한 마우스 제작소스)&lt;/p&gt; &lt;p&gt;파일을 열어보니 원하는게 아닌듯 보였는데 알고보니 PIC 용이었다. 운 좋게도 필자는 PIC18x 롬라이터를 갖고 있어서 이 소스가 뭔지 알 수 있었다. 오래전에 친구의 부탁으로 PIC18x 칩에 어셈블리를 롬라이팅 하는 프로그램을 만들어준 적이 있어서 무슨 소스인지 금방 알 수 있었다. 요새는 PIC 프로그래밍에도 C 가 쓰이고 PIC 는 PLC 대체용으로 쓰이기도 한다. 그런데 PIC 로 USB 모듈을 부착하고 마우스로 제작이 가능한거 같았다. 어쨌거나 원하는 내용은 아니었지만 생각해보면 가장 중요한 것이 물리적인 장치 아닌가? 물리적인 장치에서는 기존에 찾은 소스들이나 검색내용들과 어떤 차이가 있는지 알아볼 필요도 있다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.pudn.com/downloads128/sourcecode/comm/detail543439.html&quot; target=&quot;_blank&quot;&gt;http://www.pudn.com/downloads128/sourcecode/comm/detail543439.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 라는 소스에서 파일구성을 보면 특이한 놈이 있다.&lt;/p&gt; &lt;p&gt;usb_descriptors.c 라는 소스가 있는데 여태까지 눈여겨왔던 descriptor 라는 단어가 보일 수 밖에 없다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;/* Device Descriptor */&lt;/p&gt; &lt;p&gt;ROM USB_DEVICE_DEscRIPTOR device_dsc=&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x12, &amp;nbsp; &amp;nbsp;// Size of this descriptor in bytes&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_DEscRIPTOR_DEVICE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// DEVICE descriptor type&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0200, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USB Spec Release Number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Class Code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Subclass code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Protocol code&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; USB_EP0_BUFF_SIZE, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Max packet size for EP0, see usb_config.h&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_VID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Vendor ID&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; MY_PID, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product ID: Mouse in a circle fw demo&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x0003, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device release number in BCD format&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Manufacturer string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Product string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Device serial number string index&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Number of possible configurations&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;//Class specific descriptor - HID mouse&lt;/p&gt; &lt;p&gt;ROM struct{BYTE report[HID_RPT01_SIZE];}hid_rpt01={&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {0x05, 0x01, /* Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, /* Usage (Mouse) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, /* Collection (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, /* &amp;nbsp;Usage (Pointer) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, /* &amp;nbsp;Collection (Physical) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Buttons) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Minimum (01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Maximum (03) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x03, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (3) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Absolute) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x05, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (5) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Constant) &amp;nbsp; &amp;nbsp;;5 bit padding &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x30, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (X) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x31, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage (Y) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x81, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Minimum (-127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x7F, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Logical Maximum (127) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x75, 0x08, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Size (8) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x95, 0x02, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Report Count (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x81, 0x06, /* &amp;nbsp; &amp;nbsp; &amp;nbsp;Input (Data, Variable, Relative) &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xC0, 0xC0}&lt;/p&gt; &lt;p&gt;};/* End Collection,End Collection &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hidmouse 의 소스는 분석하지 않고 특징적인 몇개의 파일만 열어보고 위의 부분에 주목하고 닫아 버린다. 역시 컨셉은 물리 마우스가 아니라 가상 마우스이기 때문이다. 가상 마우스는 연결되면 오른쪽 아래의 트레이에 연결되었다고 풍선글이 떠야 하는 형태로 진행되어야 하는 것이 머리속의 구상이었다. 이미 driveronline 의 힌트에서 pnp 를 통해서 usb 를 인식시키라는 내용을 보았고 osronline 에서는 vhidmini 의 특정부분을 언급했으며 osronline 의 최초 질문자는 샘플의 포맷과 디스크립터를 언급했다. 다음의 사이트를 보게되면 약 90% 의 감이 오게되는데 임베디드 계통이 역시나 제일 확실하다. 시스템 프로그래머라는 황무지(wild)에서 살아가는 사람들이기 때문이다. 다만, 숫갈로 퍼먹여 주는걸 제일 싫어해서 짜증난다. 다음의 KELP 사이트의 글을 보면(&lt;a href=&quot;http://kelp.or.kr/korweblog/stories.php?story=07/02/13/3453938)&quot; target=&quot;_blank&quot;&gt;http://kelp.or.kr/korweblog/stories.php?story=07/02/13/3453938)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;글쓴이가 usb mouse 구현시 뭔가 이상하다는 식으로 적어놓고 있는 내용을 볼 수 있는데 한번 읽어보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb slave 포트를 이용하여 usb mouse를 구현하고 있습니다.&lt;/p&gt; &lt;p&gt;글쓴이 : omayaro (2007년 02월 13일 오후 02:10) 읽은수: 643&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;커널 2.6.11에서 gadget api를 이용하여 usb 마우스를 구현해 보고 있습니다.&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;처음에 모듈을 등록하기 위하여&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;static int __init my_module_init(void)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;int retval;&lt;/p&gt; &lt;p&gt;retval = usb_gadget_register_driver( &amp;amp;g_ugdDriver );&lt;/p&gt; &lt;p&gt;if (retval)&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;printk(KERN_ERR &amp;quot;[ omayaro ] module_init: cannot register gadget driver, ret=%d\n&amp;quot;, retval);&lt;/p&gt; &lt;p&gt;return retval;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;return 0;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위에서 처럼 하여 등록을 마쳤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 pc( window xp 와 fedora core4 를 사용하는 pc 2대를 한번씩 테스트 함 )에&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;usb cable을 연결하였습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그랬더니 임베디드 보드와 pc에 몇가지 반응이 오더군요..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아래의 내용은 진짜 마우스를 꼽았을때에 windows xp에서 usb descriptor를&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;분석한 내용입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x08 (8)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0000&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x01&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x02&lt;/p&gt; &lt;p&gt;Open Pipes: 1&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Endpoint Descriptor:&lt;/p&gt; &lt;p&gt;bEndpointAddress: 0x81&lt;/p&gt; &lt;p&gt;Transfer Type: Interrupt&lt;/p&gt; &lt;p&gt;wMaxPacketSize: 0x0004 (4)&lt;/p&gt; &lt;p&gt;bInterval: 0x0A&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;그리고 아래의 정보는 제가 짠 프로그램이 동작하여 pc에 등록된 정보입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: 0x0110&lt;/p&gt; &lt;p&gt;bDeviceClass: 0x03&lt;/p&gt; &lt;p&gt;bDeviceSubClass: 0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: 0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: 0x10 (16)&lt;/p&gt; &lt;p&gt;idVendor: 0x062A&lt;/p&gt; &lt;p&gt;idProduct: 0x0000&lt;/p&gt; &lt;p&gt;bcdDevice: 0x0199&lt;/p&gt; &lt;p&gt;iManufacturer: 0x00&lt;/p&gt; &lt;p&gt;iProduct: 0x00&lt;/p&gt; &lt;p&gt;iSerialNumber: 0x00&lt;/p&gt; &lt;p&gt;bNumConfigurations: 0x01&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ConnectionStatus: DeviceConnected&lt;/p&gt; &lt;p&gt;Current Config Value: 0x00&lt;/p&gt; &lt;p&gt;Device Bus Speed: Low&lt;/p&gt; &lt;p&gt;Device Address: 0x00&lt;/p&gt; &lt;p&gt;Open Pipes: 0&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;보시면 ConnectionStatus에 들어 있는 정보가 좀 틀리고 end point의 정보는 아예 없는 것을 보실수 있습니다.. 이 내용을 분석한 제 생각으로는 일단 Open Pipes의 수가 0인 것으로 보아 우선 정상적으로 연결 실패.. 가난 것으로 보이고요 end point가 없는 것으로 보아 어떤 설정또는 ep0를 통하여 세팅중에 에러가 난 것으로 보입니다...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제 질문...( 서론이 좀 길었죠??ㅡㅜ;;;; ) 제가 아직 usb 에 대해 정확히 이해를 못해서 인지는 몰라도 usb ep0를 통하여 setup이 될때 어떤 순서로 setup이 이루어 지는지 잘 모르겠습니다. 제 생각으로는&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. host가 device descriptor를 요청하여 가져감&lt;/p&gt; &lt;p&gt;2. 나머지 descriptor( configure, interface )를 가져감&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;으로 생각이 되는데요.. 순서가 저렇게 되는 것이 맞나요?? 그리고 pipe( 제 생각에는 in/out end point )가 open되는 시점이 이 언제인지 궁금합니다.. 조금 정리해서 물어본다면.. usb device가 pc에 꽂힌 후 정상 인식 되기까지 host가 device에게 요청하는 메시지의 순서가 궁금하네요~~ 그리고 언제 pipe가 오픈이 되는 지... 도 궁금합니다~~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;고수님들의 답변 기다릴게요~~&lt;/p&gt; &lt;p&gt;하루에 refresh만 5천번하는.. omayaro 였습니다...ㅠ0ㅠ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;오케이.. 뭔가 삘이오는데.. 바로 앞에서 가슴속에 담아둔 그거네.. -_-; 중요한건 바로 디스크립터(descriptor) 컨피겨(configure) 인터페이스(interface) 라는 내용이 또 나온다. 어쨌거나 저쨌거나 질문자는 실패한 사람이니까 믿을게 못된다. 여기에 달린 댓글이 중요하다. 그런데.. 역시나.. 멋진 시스템 프로그래머들 같으니라구.. ㅎㅎ 직접읽어보라.. 민망하다..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;익명 (2007년 02월 13일 오후 10:08)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 밥은 직접 떠서 드세요.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; device 연결시점에서는 default(첫번째) configuration 으로 동작합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; host 쪽에서 사용자의 요구에 의해 다른 configuration 으로 전환합니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 흔한 경우는 아닙니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 이런 방식을 사용하는 대표적인 경우는 device 쪽에 end point 가 모자랄 경우입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 간혹, host쪽 사용자에게 디버깅 포트등을 숨기기 위해서 사용하기도 합니다.&amp;nbsp;&lt;/p&gt; &lt;p&gt;--------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;역시나 댓글한번 멋지게 달려있었다. 밥은 직접 떠먹어야 한다는 말. 누가 그걸 모르나. 이쯤되면 검색에 이골이 나기 일보직전이 되고 서서히 자신감도 사라지고 짜증이 섞이기 마련이다. 이때한번 refresh 가 필요한데 검색은 계속되어야 한다.. 쭈~욱.. 점점 검색하다보면 Filter Driver 에 대한 내용이 나오기도 하고 처음부터 검색이 되더라도 알아먹지 못했던 내용이 두번째 검색하다 모르고 똑같은걸 또 보게되면(즉, 본걸 나중에&lt;/p&gt; &lt;p&gt;또 봤을때) 이해가 되기 시작하는 부분이 생겨나기 시작한다. 바로 다음의 부분들이 그러한 부분들이라 하겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;bodnar&lt;/p&gt; &lt;p&gt;February 11th, 2007, 05:58 AM&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am trying to fix a part of the report descriptor on an existing USB HID device that woked fine but&lt;/p&gt; &lt;p&gt;has problems on Vista. It installs&lt;/p&gt; &lt;p&gt;and everything is OK with it but DirectX refuses to see it due to some inconsistency in the report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I understand that I would need to write a filter driver to fix that.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have downloaded recent WDK and looked at the samples, specifically HID\Firefly sample but I cannot figure out&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;how to alter&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Report Descriptor data when the driver receives IRP_MN_START_DEVICE in DispatchPnP. I can see how PDEVICE_OBJECT&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DeviceObject is passed&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;to it but mmm.. how do I get access to HID device details so I can alter it?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;When I look inside HID\Vhidmini virtual HID minidriver I can see exactly what I would want to use in the&lt;/p&gt; &lt;p&gt;filter driver:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I am a bit lost... Any help is appreciated.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;------------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;미국말로 뭐라 지껄이는지 전혀 관심없다. 오로지 Report Descriptor data when the driver receives IRP_MN_START_DEVICE&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;in DispatchPnP 라는 문장과 다음의 소스 두부분이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;ReportDescriptor = NewReportDescriptor;&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength = ...;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이 글에서 필자가 어느타임에 어디를 수정해야 할지 방향을 구체적으로 잡아나갈 수 있는 단초가 마련되기 시작한다. 즉, DispatchPnP 에서 IRP_MN_START_DEVICE 를 받았을때 Report Descriptor data 가 관계가 있다는 점이고 ReportDescriptor 를 NewReportDescriptor 로 할당하는 조작을 잡아낼 수 있다. 원래는 vhidmini 라는 Microsoft 사의 공식샘플이 어떻게 생겨먹었는지&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;잠시 소스 일부분을 보자면&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Store the registry report descriptor in the device extension&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReadReportDescFromRegistry = TRUE;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor.DescriptorList[0].wReportLength =&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(USHORT)RegistryReportDescriptorLength;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;위의 모습처럼 되어있다. 그런데 저 미국아가 한 짓은 deviceInfo-&amp;gt;ReportDescriptor = RegistryReportDescriptor 를 NewReportDescriptor 로 바꿨다는 것이다. 그러니 필자도 역시 이 부분을 건드리게 될 것이란 소리가 된다. 그러므로 수정을 가할 부분을 한 부분 구체적으로 알아먹었다. 이 글의 맨 처음 시작부분의 Numega Soft 의 소스라고 되어있는 부분을 보자.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;// The HID report descriptor for this device &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;// (taken from USB/HID specification) &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR MouseHidReportDesc[] = { &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, // Usage Page (Generic Desktop), &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x02, // Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x01, // Collection (Application), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x01, // Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xA1, 0x00, // Collection (Physical), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, // Usage Page (Buttons), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x19, 0x01, // Usage Minimum (01), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x29, 0x03, // Usage Maximun (03), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, // Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;해당 부분을 보면 이제서야 뭔가 감이 오기 시작하게 되는 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드디어;;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;middot;작성일 &amp;nbsp; &amp;nbsp; 2007.01.28:15.25 (일)&lt;/p&gt; &lt;p&gt;&amp;middot; 작성자 &amp;nbsp; &amp;nbsp; rechoco&lt;/p&gt; &lt;p&gt;&amp;middot; 조 회 &amp;nbsp; &amp;nbsp; 487&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;hid minidriver 테스트 살짝 성공~&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;샘플소스를 구해서 레포트 디스크립터랑 익스텐션 조금 손만 본거지만.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;디바이스에서 데이터를 hid포멧에 맞춰서 주는게 아니라서..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;강제로 제가 바꿔줘야 했거든요ㅋ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;마우스로 테스트 해봤더니 쭉쭉 잘옮겨지더군요&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;물론 목표한 디지타이져는 아직 안됩니다;;&lt;/p&gt; &lt;p&gt;(와컴것 분석했더니 절대좌표모드일때도, 마우스 플래그를 쓰더군요&lt;/p&gt; &lt;p&gt;xp에서는 디지타이져가 지원이 안되니까 절대좌표 &amp;quot;처럼&amp;quot; 마우스좌표로 작업합니다.&lt;/p&gt; &lt;p&gt;저도 그렇게 하긴했는데. 영 개운하지가 않아서;;&lt;/p&gt; &lt;p&gt;디지타이져가 비스타에서는 지원 된다길래 해봤는데 실패했다는;;)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;제가 참고한 샘플은 WDK의 vhidmini 소스입니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;xp용으로 inf파일하고 소스파일 조금 수정하시면 빌드도 잘되고..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;헛짓거리중에 잠깐 들러봤습니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버 온라인님들 모두 화이팅하세요!!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아쉽게도 이 글은 가상 마우스인지 실제 마우스의 필터드라이버를 만든것인지 알길이 없어서 단지 말 그대로 희망만 주는 글인데 되긴 되나부다 정도로만 넘겨야 했다. 중요한 개념가닥을 잡아내는 파편과도 같은 내용들은 모두 끝났고(사실 더 많지만..) 다음의 세가지 정보의 검색이 사실상 전체적인 개념(컨셉)을 모두 얻도록 해주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;1.&amp;nbsp;&lt;a href=&quot;http://www.eggheadcafe.com/software/aspnet/32296449/virtual-usb-mouse-device.aspx&quot; target=&quot;_blank&quot;&gt;http://www.eggheadcafe.com/software/aspnet/32296449/virtual-usb-mouse-device.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Virtual USB Mouse Device only shows as generic HID device. - tomca&amp;gt;&lt;/p&gt; &lt;p&gt;08-May-08 05:16:00&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I wrote a bus driver that generated virtual USB PDO for Printer, Scanner, and&lt;/p&gt; &lt;p&gt;SmartCard. &amp;nbsp;It worked fine before. &amp;nbsp;Recently, I was requested to provide a&lt;/p&gt; &lt;p&gt;virtual USB mouse PDO. &amp;nbsp;What I did was as following steps&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. An usermode application access bus driver to add a new PDO&lt;/p&gt; &lt;p&gt;2. bus driver use IoCreateDeviceSecure to create a new device and invalid&lt;/p&gt; &lt;p&gt;bus relation.&lt;/p&gt; &lt;p&gt;3. PNP manager found this new device, it will query the hardwareid, device&lt;/p&gt; &lt;p&gt;instanceid, and compatible id.&lt;/p&gt; &lt;p&gt;4. I provide USB\Class_03&amp;amp;SubClass_01&amp;amp;Prot_02 as compatible ID&lt;/p&gt; &lt;p&gt;5. System find this is a HID device and start to query Device Descriptor,&lt;/p&gt; &lt;p&gt;Configuration Descriptor, and HID descriptor.&lt;/p&gt; &lt;p&gt;6. Since this is a virtual mouse, bus driver gives HID descriptor without&lt;/p&gt; &lt;p&gt;hardware. &amp;nbsp;I copy a standard mouse device&amp;#39;s HID descriptor (3button usb&lt;/p&gt; &lt;p&gt;mouse) to caller.&lt;/p&gt; &lt;p&gt;7. From Device Manager, I can see a HID device shows up, &amp;nbsp;but there is not&lt;/p&gt; &lt;p&gt;mouse device shows up.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If I plug in a real usb mouse, I can see system create a HID device first,&lt;/p&gt; &lt;p&gt;then HIDClass driver create a PDO for mouhid driver. &amp;nbsp;Is anyting wrong I did?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have carefully checked the USB data sent to caller, everything is ok, but&lt;/p&gt; &lt;p&gt;system doesn&amp;#39;t like this device as mouse, &amp;nbsp;Just consider it as generic USB&lt;/p&gt; &lt;p&gt;HID device.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Could someone give me help?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Thanks!&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;유저모드&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;2. KSP(www.ksyspro.org) 라는 곳에서 작성한 &amp;quot;USB강의자료.PDF&amp;quot; 라는 파일이 인터넷에서 검색되었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;내용의 제목은 &amp;quot;9차 정기 세미나 강의 자료&amp;quot; USB Device Driver 강의였다. 아쉽지만 원래 이런&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;사이트는 문이 닫혀있다. (원래 그런거니까 이해를 해야한다.. -_-; 얼마나 힘들겠는가..? )&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 내용이 작살이다. 이건 그냥 인터넷에서 받아서 보라.. 전체적인 개념정립이 이루어진다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;(아마 앞서서 했던 기본적인 검색뻘짓이 없이는 읽을 수 있는 내용이 아니었으리..)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;---------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;3. MSDN &amp;amp; ReactOS 소스 중의 USB 부분에 있는 Mouse 드라이버&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 항상 마지막은 MSDN 의 승리이다. 전체적인 모든 내용이 다 들어있다. 빌어먹을 일정수준이상이&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;되지 않으면 처음에 백날봐도 못알아 처먹는다는 것이 문제다. 커널이던 응용프로그래밍이던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이건 차이가 없다. 지금도 응용프로그래밍도 못알아 먹는게 태반이니까. 어쩔수 없이 이 고생을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;치르는건 MSDN 을 보기위해서가 아닐까. (COM 프로그래밍도 MSDN 이 제일 많은 정보가 있다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;이 말을 증명해보겠음!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;다음은 MSDN 의 vhidmini.h 라는 파일에 능구렁이처럼 맨 마지막 부분에 주석으로 처리되어있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[vhidmini.h 파일]&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;/*&lt;/p&gt; &lt;p&gt;//&lt;/p&gt; &lt;p&gt;// Here is sample descriptor that has two top level collection - mouse&amp;nbsp;&lt;/p&gt; &lt;p&gt;// collection and &amp;nbsp;vendor defined collection with a custom feature item. If&amp;nbsp;&lt;/p&gt; &lt;p&gt;// you want to provide sideband communication with your hidmini&amp;nbsp;&lt;/p&gt; &lt;p&gt;// driver, you can add a custom collection with the collection provided&amp;nbsp;&lt;/p&gt; &lt;p&gt;// by the hardware and open the custom collection from an app to&amp;nbsp;&lt;/p&gt; &lt;p&gt;// communicate with the driver.&lt;/p&gt; &lt;p&gt;// 여기 두개의 탑레벨 모음인 샘플 디스크립터가 있다.&lt;/p&gt; &lt;p&gt;// 커스텀 피처아이템을 가진 마우스 모음과 벤더 정의 모음이다.&lt;/p&gt; &lt;p&gt;// 니가 만약 너의 hidmini 드라이버를 가지고 사이드 밴드 통신을 제공하길&lt;/p&gt; &lt;p&gt;// 원한다면, 너는 하드웨어에서 제공되는 모음과 응용프로그램으로부터 드라이버&lt;/p&gt; &lt;p&gt;// 통신하는 것까지 개인모음을 추가할 수 있다.&lt;/p&gt; &lt;p&gt;// (역주: 즉, 몬소리냐면 이거 앞에서 선언한 DefaultReportDescriptor 대신에&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이걸 그냥 가져다가 써라. 마우스 예제다. 이 말이나 마찬가지임.&lt;/p&gt; &lt;p&gt;// &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;여기에 니가 원하는거 추가해서 쓰라는 소리임. 이미 소스에 다 있었음.)&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; //Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; //Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; //REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; //Usage (Pointer),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; //Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; //Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; //Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; //Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; //Logical Minimum (0),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; //Logical Maximum (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x03, &amp;nbsp; &amp;nbsp; //Report Count (3),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x01, &amp;nbsp; &amp;nbsp; //Report Size (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x02, &amp;nbsp; &amp;nbsp; //Input (Data, Variable, Absolute), ;3 button bits&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x01, &amp;nbsp; &amp;nbsp; //Report Count (1),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x05, &amp;nbsp; &amp;nbsp; //Report Size (5),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x01, &amp;nbsp; &amp;nbsp; //Input (Constant), ;5 bit padding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; //Usage Page (Generic Desktop),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x30, &amp;nbsp; &amp;nbsp; //Usage (X),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x31, &amp;nbsp; &amp;nbsp; //Usage (Y),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x81, &amp;nbsp; &amp;nbsp; //Logical Minimum (-127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x25, 0x7F, &amp;nbsp; &amp;nbsp; //Logical Maximum (127),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75, 0x08, &amp;nbsp; &amp;nbsp; //Report Size (8),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95, 0x02, &amp;nbsp; &amp;nbsp; //Report Count (2),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x81, 0x06, &amp;nbsp; &amp;nbsp; //input (Data, Variable, Relative), ;2 position bytes (X &amp;amp; Y)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //End Collection,&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x06,0x00, 0xFF, &amp;nbsp; // USAGE_PAGE (Vender Defined Usage Page) &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // COLLECTION (Application) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85,0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_ID (2) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // USAGE (Vendor Usage 0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // LOGICAL_MINIMUM(0) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x26,0xff, 0x00, &amp;nbsp; // LOGICAL_MAXIMUM(255) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x75,0x08, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_SIZE (0x08) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x95,0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // REPORT_COUNT (0x01) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xB1,0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // FEATURE (Data,Ary,Abs) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xC0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// END_COLLECTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;};&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;*/&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;자.. 이제 끝났다~ 라고?&lt;/p&gt; &lt;p&gt;한숨을 쉬기에는 너무 이르다. 대부분의 혼선과 문제점은 여기서부터 시작되기 때문이다. Microsoft 사의 WinDDK 라는 개발킷에 있는 vhidmini 샘플은 그저 샘플일 뿐이기에 정상작동이 되는지 확인을 해야하기 때문이다. 필자는 위에서 주석처리 되어있는 마우스 예제 DefaultReportDescriptor 의 주석을 풀고 기존에 있던 샘플 DefaultReportDescriptor 와 교체했다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;드라이버를 컴파일하는 방법은 여기서 설명하지 않는다. 그냥 WinDDK 설치후 프로그램 메뉴에서 XP 용 콘솔창을 열고 vhidmini 디렉토리로 이동후 nmake 명령을 내리면 컴파일이 가능한 것을 여기서 구차하게 다 설명을 할순없다. (그러면서도 벌써 설명까지 다 해주는 친절한 금자씨.. ㅎ) 이제 vhidmini 드라이버를 컴파일하고 장치를 인스톨 시키면 오른쪽 화면아래 트레이에 드라이버가 인식되었다고 뜰 것을 기대했다. 우리가 흔히 새 마우스를 USB 포트에 꽂으면 장치가 검색되었다고 뜨는걸 볼 수 있지 않은가? Human Interface Device(휴먼인터페이스장치) 어쩌구라는 메시지와 함께 잠시뒤에 마우스가 발견되었다는 식의 그런 메시지를 기대했다. 그러나 결과는 참담했고 미궁속으로 계속해서 빠져들고 말았다. 왜 그랬을까..? 비단 이 문제는 필자만의 문제가 아니었다. vhidmini 샘플 드라이버를 처음접하는 모든 프로그래머들이 모두 이같은 삽질의 미궁속에 빠져든다는 점을 검색을 통해서 알 수 있었다. 바로, MS 의 함정을 말이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;여기서 다시 위와 같은 오류를 범해나가는 설명을 할 것이다. 어떤식으로 접근할 것인가와 얼마나 많은 뻘짓이 필요했는가에 대해서 설명할 필요가 있다고 본다. 그로인해서 얻은 것들은 상당히 많이 있다. 바로 단거리 스피드로 달리는 사람들은 놓칠수 있는 정보를 마라토너들은 두루두루 보고 달릴수 있는 것처럼 주변지식들을 충분히 얻을수 있다는 장점이 있다. 이 문서를 쓰는것 자체가 사실 기술적인 것에 너무 치우치는 쪽 보다는 학습방법을 알리는 병행효과를 얻기위한 것이기 때문에 무엇을 보았는지 지금부터 과정을 설명할 것이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;앞서서 우리는 가상마우스를 만들기 위해서는 Virtual HID Device 를 만들수 있어야 한다는 점만 인식하고 출발했다. 완전히 지식이 전무한 상태에서 기본 골격코드마져 없는 허당상태로 시작할 수 있는 프로그래머는 아무도 없다. 이미 가상마우스 프로그램을 만들어본 경험이 있는 프로그래머라도 기본적인 코드의 골격없이 모든걸 직접 작성하는걸 기대하는건 어려운일이란 얘기이다. 그래서 우리가 앞에서 선행작업을 한 것이 바로 그 뼈대를 찾기위한 작업이었고, 숱한 오류과정을 거치며 우리가 만들 가상장치의 핵심뼈대를 발굴하고 비교 분석하여 선정하는 작업까지 마쳤다. 그리고 우리가 만들 장치에서 가장 중요한 핵심키포인트를 잡아내는 학습방법까지 소개하였다. 결론적으로 앞에서 습득한 사항들을 요약해 보자면..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. 우리가 만드는 Virtual HID Device 는 mouse 또는 keyboard 와 혼합형태(혹은 단독일수도.. 그건 선택사항)이며 가상 USB 를 통해서 장치가 인식되어야 한다. 이 점은 프로그래밍적으로 정보를 수집하기 전에 머리속으로 구상한 내용에 속한다.(나중에 언급하겠지만 실제 설치/작동은 프로그래머의 상상과 약간 다르다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;2. 여러 정보들을 수집하여 비교분석 한 뒤 그 중에서 vhidmini 라는 Microsoft 사의 WinDDK 개발킷 공식샘플을 채용하기로 최종결론을 내렸다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;3. vhidmini 라는 샘플을 운용하기위해 요구되는 스킬은 USB 의 HID 라는 인터페이스이며 이 인터페이스의 핵심 키포인트는 바로 Report Descriptor 라는 Descriptor 를 어떻게 기술할 것인가에 달려있다는 점을 알아낼 수 있다. 이 점은 이미 학습방법으로 어떻게 그 특징을 캣치하는지 보여주었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;4. 우리는 최종적으로 Virtual HID Device 를 마우스로 인식시키기위해 Report Descriptor 라는 기술자(descriptor)를 찾아내야 했으며 적당한 기술자를 vhidmini.h 에서 발견하였다. 이 기술자를 Default 로 맞추고 컴파일 한 뒤 VMware 에 설치된 윈도우에서 설치하면 실제장치로 인식된다는 것까지 모두 정립하였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;다음의 명령어를 이용해서 장치를 설치할 수 있다. 즉, 윈도우가 설치된 VMware 에는 vhidmini.sys 와 vhidmini.inf 그리고 devcon.exe 라는 총 세개의 파일이 복사되어야 한다. devcon 이라는 툴은 윈도우 장치관리자가 할 수 있는 모든 기능+ 를 콘솔에서 명령내릴수 있도록 해주는 커맨드유틸이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[설치명령]&lt;/p&gt; &lt;p&gt;devcon install vhidmini.inf &amp;quot;{D49F883C-6486-400a-8C22-1A9EF48577E4}\HID_DEVICE&amp;quot; 위와 같이 VMware 에 컴파일된 vhidmini 드라이버 파일들을 모두 복사한 뒤에 설치명령을 내린다. VMware 의 화면에는 신뢰를 받지못한 장치 드라이버 설치시에 뜨는 경고문구가 뜨게될 것이다. &amp;lt;계속&amp;gt; 이라는 버튼을 클릭하게되면 sys 파일을 찾지못해 디렉토리 지정창이 한번 더 뜰 것이다. 그 이유는 현 설치위치(devcon 명령어 실행디렉토리 위치) 밑에 i386 이라는 디렉토리에 sys 파일이 존재한다는 가정을하기 때문이다. 즉, INF 파일이 존재하는 위치를 기준으로 그 하위 i386 디렉토리에서 드라이버파일을 찾는다. 그래서 드라이버를 못찾는다는 창이 뜨게된다. 이건 그냥 적당히 vhidmini.sys 파일이 있는 디렉토리를 지정하면 알아서 설치가된다. 그런데.. 우리가 예상했던 설치모습이 아니었다. 그건 필자만의 착각이었을런지도 모르겠지만, 일단 이렇게 장치의 설치과정은 밍밍하게 끝나버린다. 이제 장치가 제대로 인식되었는지 확인을 하기위해 &amp;quot;장치관리자&amp;quot; 를 오픈한다. 그러면 휴먼인터페이스 장치쪽에 두가지 장치가 새롭게 추가되어있는 것을 보게될 것이다. 그런데, 뭔가 생각하던것과는 다르게 인식된 듯한 생각을 가지게 될 것이다. 그 장치는 그저 Generic HID 장치일 뿐 마우스가 아니다. 이게 도대체 어찌된 영문인가? 뭔가 잘못된 것이 있는지 확인해보고 수도없이 DefaultReportDescriptor 를 수정 해봐도 역시나 마찬가지로 마우스로 인식되질 않았다. Revert to snapshot 을 수도없이 반복하며 디스크립터 (Report Descriptor) 를 수정해도 역시나 반응은 일반장치(Generic HID) 일 뿐이었다. 정확히 말하면 VMware 기준으로 XP 에서 장치를 설치했을때 설치되는 이름은 두가지였다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;quot;HID 준수장치&amp;quot;&lt;/p&gt; &lt;p&gt;&amp;quot;Root Enumerated HID Device (sample)&amp;quot;&lt;/p&gt; &lt;p&gt;위의 두가지 장치가 설치된다. 우리가 원하는 것은 &amp;quot;HID 준수장치&amp;quot; 가 &amp;quot;HID 규격 마우스&amp;quot; 로 인식되어야만 한다. 그런데, 이런현상이 계속 지속되어 혼란이 가중될 뿐이었다. 어딘가 필자가 모르는 키포인트가 또다시 존재할 것이리라 생각하고 이 현상을 겪는 어딘가에 있을 동지에게 SOS 를 날려야 했다. 우리의 구글형님이 그러한 고충을 겪는 사람들을 모두 한자리로 집합시켜주었다. 그런데.. 구글이 불러모은 검색정보들은 하나 같이 모두 헛소리들 뿐이었다. 근접은 했어도 정답이 하나도 없는게 아닌가.. 제길.. FireFox 에서 탭을 약 20개 가까이 띄워놓고 검색에 검색을 반복하며 필자의 Report Descriptor 정보중 어디가 잘못되었는지를 찾아내기 위해서 안간힘을 쓰고 있었다. Report Descriptor 라는 것은 무엇인가? USB 라는 장치가 자기의 정보를 상위장치에 넘겨서 인식되도록 하기위한 마치 신분증과도 같은 것이다. 어디서 태어났고 어디서 자랐으며 나이는 몇살이고 남성인지 여성인지 기타등등.. 마치 이런정보처럼 인식정보를 쏘기전에 셋팅하는 값이다. 이 값이 하나라도 잘못될 경우에 장치는 절대로 제대로 인식되지 않는다. 항상 사람이 고생을 하려면 깨닫는 과정에서 착각을 일으키게된다. 필자는 vhidmini.h 파일에 있는 공식적인 마우스(예제) 디스크립터 주석을 풀어서 대체시켰다. 필자는 그 디스크립터를 믿지 못했다. 어딘가 오류가 있거나 한가지를 수정함으로&lt;/p&gt; &lt;p&gt;인해서 다른것까지 수정해야하는 문제점이 걸렸다거나 그런류로 생각할 수 밖에 없었다. 다음은 필자와 같은 문제점을 겪는 사람들에 대한 이야기다. 그다지 위안도 되지 않았고 결국 구글형님을 통해 문제의 정확한 해결점을 찾아낼 수 없었지만.. 그 과정에서 문득 떠오르는 영감을 주었기에 그 과정을 그려보고자 한다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2007-03/msg00258.html&quot; target=&quot;_blank&quot;&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2007-03/msg00258.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;thank for your advice.&lt;/p&gt; &lt;p&gt;i forget to assign REPORT_ID for each report desc.&lt;/p&gt; &lt;p&gt;It works now.&lt;/p&gt; &lt;p&gt;However, i migrated the corrected report to &amp;quot;hidfake&amp;quot;. (Walter Oney &amp;#39;s sample)&lt;/p&gt; &lt;p&gt;The system pop up 3 &amp;quot;Found New Device Wizard&amp;quot; window and identfy it as &amp;quot;Unknow Device&amp;quot;.&lt;/p&gt; &lt;p&gt;Any difference detween these 2 drivers&amp;#39; enumeration?&lt;/p&gt; &lt;p&gt;Appreciated.&lt;/p&gt; &lt;p&gt;(필자요약: REPORT_ID 를 빼먹었다. 작동된다. 그런데 hidfake 꺼를 배꼈다. 그랬더니 &amp;quot;알려지지않은 장치&amp;quot; 라는 새로운 장치로 &amp;quot;하드웨어 찾기&amp;quot; 가 세개나 뜬다. 나머지는 해석할 필요 없겠다.. 왜 그런가? 라는 질문 이라고 생각하고 넘어간다..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;quot;Doron Holan [MS]&amp;quot; wrote:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; you only need one HID minidriver. from it, a keyboard and a mouse can&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; be&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; enumerated. you just have to put each device into its own top level&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; collection. If you are having trouble, i would find a USB HID that already&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; does this and look at its HID descriptor&lt;/p&gt; &lt;p&gt;(필자요약: 이놈이 다른 게시판에도 있는걸보면 좀 하는거 같다. 대충 번역하면 너는 오직 한개의 HID 미니드라이버만 필요할 뿐이다. 그리고 키보드나 마우스가 열거될수 있는 것으로 부터, 그리고 각각의 그 자신의 탑레벨 모음속에 각장치들을 넣어야만 한다. 만약 문제가 있다면, 니가 만든 USB HID 를 어쩌구 저쩌구.. 뭔가 HID Descriptor 와 연관이 있겠거니하고 그냥 넘어감..)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;I&amp;#39;m pretty sure you will need to break up hte device into a Mouse device and Keyboard device. (i.e two drivers,&lt;/p&gt; &lt;p&gt;one with a report descriptor for a keyboard and one for a mouse)&lt;/p&gt; &lt;p&gt;The inf files should not refer to HID\MyVirtualHidDevice - these id&amp;#39;s need to be picked up from keyboard.inf or&lt;/p&gt; &lt;p&gt;msmouse.inf - idealy reporting the compatible id of HID_SYSTEM_KEYBOARD or HID_SYSTEM_MOUSE (i think)&lt;/p&gt; &lt;p&gt;(필자요약: 마우스와 키보드장치속에 hte 장치를 깨야할 필요가 있다라고 해석해야 하나.. &amp;nbsp;이놈이 주장하는 내용은 일단, report descriptor 에 키보드와 마우스가 하나로 일치되어있는가를 확인하라는 내용과 HID\MyVirtual HidDevice 라는 장치명으로 되어있는 vhidmini.sys 샘플이 이름이 잘못되어서 그런게 아니냐는 속임수에 빠지기 쉬운 의견을 제시해 놓고 있다. 마치.. 네이버 지식인인가? 하지만 여기서 얻을 수 있는 점이 있는데 HID_SYSTEM_KEYBOARD, HID_SYSTEM_MOUSE 라는 지시어이다. 어설픈건 혼란을 가중시키는데 원래는 HID_DEVICE_SYSTEM_KEYBOARD 이고 HID_DEVICE_SYSTEM_MOUSE 가 맞는거니까 속지말자. 뒤에서 설명하겠지만 이걸 알아 듣기 위해서 새로운 개념을 습득하게 된다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Hi,&lt;/p&gt; &lt;p&gt;I write a HID minidriver with standard Mouse and Keyboard report&lt;/p&gt; &lt;p&gt;descriptors.&lt;/p&gt; &lt;p&gt;It is based on vhidmini in Windows Server 2003 DDK.&lt;/p&gt; &lt;p&gt;The driver work fine and I can read/write the report from the&lt;/p&gt; &lt;p&gt;device.&lt;/p&gt; &lt;p&gt;The Device Manager shows it is HID-compliant device in HID class,&lt;/p&gt; &lt;p&gt;but&lt;/p&gt; &lt;p&gt;the&lt;/p&gt; &lt;p&gt;Mouse Class and Keyboard Class have none.&lt;/p&gt; &lt;p&gt;How should I do so that it can be a mouse device and keyboard&lt;/p&gt; &lt;p&gt;device?&lt;/p&gt; &lt;p&gt;Should I modify the INF file? My driver&amp;#39;s INF is almost same as the&lt;/p&gt; &lt;p&gt;vhidmini&amp;#39;s.&lt;/p&gt; &lt;p&gt;(필자요약: Windows Server 2003 DDK 로 vhidmini 를 만들었다는 식인데 장치명이 HID-compliant(일반 복합HID 장치)로 인식되는데 마우스 클래스와 키보드 클래스가 없다고 말한다. 어떻게 마우스와 키보드 장치로 인식시키는 것이냐고 물어본다. 자기가 INF 파일을 수정해야 하는지 물어본다. 그리고 INF 파일은 vhidmini 와 거의 같다고 말한다. 이 사람이 겪는 증상이 필자가 겪는 증상과 100% 일치한다. 그런데 불행히도 이 글에는 더이상의 답변이 달려있지 않았다. 눈물의 고배를 마시고 돌아서야 하는 이 저린마음.. T.T 어쩔수 없이 또다시 구글형님의 도움을 받아야한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이 질/답들에서 배운 것은 검증해봐야하는 대상들이다. 일단, HID Report Descriptor 가 잘못되었는지 검증해야하며 INF 파일이 잘못되었는지 검증해봐야하고 &amp;quot;한참을 헤메게 만든 요인이었지만&amp;quot; REPORT ID 에 대해서도 검증해봐야 한다는 몇가지 결론을 얻은채 새로운 검색활로를 모색해보게 된다. 이 검색은 첫 발을 내딘수준에 불과하다. 거의 48시간을 오로지 이 문제를 해결하기 위해서 정보들을 모아야 했다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techtalkz.com/microsoft-device-drivers/297875-loading-driver-hid-class.html&quot; target=&quot;_blank&quot;&gt;http://www.techtalkz.com/microsoft-device-drivers/297875-loading-driver-hid-class.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Loading a driver on HID class&lt;/p&gt; &lt;p&gt;Hi all,&lt;/p&gt; &lt;p&gt;I have a USB device that exposes a HID interface. It is not a mouse or&lt;/p&gt; &lt;p&gt;a keyboard, just a general HID device. Device Manager displays it as a&lt;/p&gt; &lt;p&gt;&amp;quot;HID-compliant device&amp;quot;.&lt;/p&gt; &lt;p&gt;Now I would like to install a device driver on it and use the HID&lt;/p&gt; &lt;p&gt;interface to communicate with.&lt;/p&gt; &lt;p&gt;My INF refers the HID\VID_xxxx&amp;amp;PID_xxxx string and my driver gets&lt;/p&gt; &lt;p&gt;loaded.&lt;/p&gt; &lt;p&gt;So I get the PDO from AddDevice and I need the FileObject to&lt;/p&gt; &lt;p&gt;communicate using IOCTL_HID_SET_FEATURE and IOCTL_HID_GET_FEATURE. But&lt;/p&gt; &lt;p&gt;I cannot retrieve it; I use the FireFly sample and the function&lt;/p&gt; &lt;p&gt;FireflyOpenStack to retrieve the FileObject form the PDO but it fails&lt;/p&gt; &lt;p&gt;in my driver with error 0xC000000E (STATUS_NO_SUCH_DEVICE) when&lt;/p&gt; &lt;p&gt;calling ZwOpenFile.&lt;/p&gt; &lt;p&gt;What&amp;#39;s wrong? The pdoName of the file open by ZwOpenFile is something&lt;/p&gt; &lt;p&gt;like &amp;quot;\Device\00000096&amp;quot;. Is it possible to get the SymbolicLinkName&lt;/p&gt; &lt;p&gt;instead?&lt;/p&gt; &lt;p&gt;If someone could help...&lt;/p&gt; &lt;p&gt;Thanks, Roger&lt;/p&gt; &lt;p&gt;(필자요약: HID 인터페이스를 노출하는 USB 장치를 만들었다. 그런데 그게 마우스나 키보드가 아니네? 단지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;일반 HID 장치인거야. 디바이스 디스플레이에 보면 &amp;quot;HID-compliant device&amp;quot; 라고 표시되네.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;횽님들.. 알려주십쇼.. 뭐 이런 내용식으로 글을 써놨다. 그래도 아는게 많은 사람이라서 그런지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;정보들을 많이 뿌려놨는데 독이되는 요소들이 있지만, 덤으로 알게되는 요소들도 그 못지않게&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;많다. IOCTL_HID_SET_FEATURE 과 IOCTL_HID_GET_FEATURE 에대한 얘기는(추후 구현되어야 하는 내용)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좋은 정보임에 틀림없다. 그런데 우리가 원하는 답을 얻지는 못하고 단지 INF 파일에 VID 와&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PID 스트링이 문제의 시발점이 될수도 있지는 않은가 하는 의심을 해볼수 있다. 물론, 그게 해답은&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;아니지만 추가정보를 검색해야할 키워드로써 대상물망에 넣어두자. VID 란 벤더아이디를 의미하고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;제작사의 고유식별번호이며, PID 란 프로덕트 아이디 즉, 제품번호이겠다. 이게 하드웨어는 모두&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;고유하다고 하는데 과연 이 때문에 마우스나 키보드로 인식이 안되고 일반장치로 인식되는 것일까?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;when are you trying to open a handle? during AddDevice or&lt;/p&gt; &lt;p&gt;IRP_MN_START_DEVICE? neither will work b/c a file create can only occur&lt;/p&gt; &lt;p&gt;once the start irp has come back to the pnp manager. so to make this work i&lt;/p&gt; &lt;p&gt;would&lt;/p&gt; &lt;p&gt;a) register a custom device interface GUID&lt;/p&gt; &lt;p&gt;b) register for device interface arrivals on your custom guid. when you&lt;/p&gt; &lt;p&gt;get called, open your stack like FireFly does&lt;/p&gt; &lt;p&gt;you will also need to register for handle notifications on the file handle&lt;/p&gt; &lt;p&gt;that you open so that you can gracefully disable the device. If you use the&lt;/p&gt; &lt;p&gt;KMDF firefly sample, the WDFIOTARGET object does this for you&lt;/p&gt; &lt;p&gt;(필자요약: 답변중에 하나인데 이 답변은 질문자의 추측보다 더 가관이다. IRP_NM_START_DEVICE 나 AddDevice 등록시 (필자는 커널을 몰라서 몬소린지 모르지만 이건 아니다정도의 감은 있었다.. -_-;) 하라는 식으로 답변이 달려있는데 KMDF 까지 들먹거리는걸로 봐서는 논점에서 많이 빗나갔다. KMDF 는 새로운 드라이버 개발 프레임워크인데 질문자가 그걸 물어본게 아니다. 기존의 방법으로 설명해줘야하는 것이 옳은데 그렇지도 않았고, 너무 많은 작업을 추가하라고 주문하는거보니 필자의 생각과 달랐다. 필자의 감은 Report Descriptor 만으로도 해결될 문제라고 속삭이고 있었기 때문에 이 답은 해결책이 아니었다. 다른 답변중에는 URB 를 보내라는 말도 있었다. 모두 무시한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;지금 거론하는 필자의 문제해결 방법은 링크를 보여주면서 찾아나가는 방법을 설명하고 있다. 그렇기에 링크역시 필자가 검색해서 누른 순서대로 임을 밝힌다. 다음으로 찾은 것은 MSDN 의 설명이다. 그런데 MSDN 의 설명은 항상 깨달음을 얻은뒤에나 값진 보물이 되지 깨달음을 얻기전까지는 그저 잘 만들어진 명세서에 불과하다고 느낄때가 많다. 마치 선생님이 &amp;quot;공부하라&amp;quot;고 그렇게 들볶던 말들이 성인이 된 뒤에 &amp;quot;정답&amp;quot; 이라고 느끼는 것처럼 느낀뒤에만 알 수 있는 것들이 기록되어 있는게 MSDN 과도 같다. 왜 그땐 몰랐지? 왜 그땐 안봤지? 나중에 이런말 자주하게 될거다. ㅎㅎ 그런데.. 역시.. -_-; 이 링크를 보던 시점(현 글을 쓰는 시점기준으로 하루전)만 해도 이 링크는 그저 도움이 안되었다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa487252.aspx&quot; target=&quot;_blank&quot;&gt;http://msdn.microsoft.com/en-us/library/aa487252.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(필자요약: 설명이 잘 되있다. 읽어보라.. 해결책도 들어있다. 그런데 그냥보면 절대 모른다. 개고생하면 그때는 답이 보이지만 그냥보면 모른다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&quot; target=&quot;_blank&quot;&gt;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 이 사이트는 중국사이트인데 읽을수가 없다. 몇가지 좋은 키워드와 코드가 있는데 해결책은 아니고 나중에 마우스나 키보드를 구현할때 참고할 만한 코드가 아주 조금 있을 뿐이었다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&quot; target=&quot;_blank&quot;&gt;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 필자가 겪는 문제를 어느정도 일부분은 해결한 것 같기도하고 그렇지 않은거 같기도 한데 희한한&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 삽질을 하고 있었다. Descriptor 를 계속해서 바꿔가면서 테스트하는 것을 물어보고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 마우스와 키보드를 인식시키기 위해서 vhidmini 를 기본베이스로 디스크립터를 조작하는데 설치가&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 안된다는 그런 질문이었다. 질문양이 많아서 짤라붙이기는 못하겠다. 답글을 보자.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Adrian Schlesinger&lt;/p&gt; &lt;p&gt;xxxxxx@baum.ro&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 24 Sep 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 7&lt;/p&gt; &lt;p&gt;RE: Simulate keystrokes&lt;/p&gt; &lt;p&gt;I have detected what was wrong:&lt;/p&gt; &lt;p&gt;1. When adding the report ID item to the keyboard top-level collection, an additional byte should be returned to&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;the system at the beginning of the data, specifying that report ID.&lt;/p&gt; &lt;p&gt;2. Communication from user mode did not work because when cycling through the HID devices,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;in addition to vendor ID, product ID and version, the usage specified for the additional end point should also&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;be matched (with Vendor Usage 1), otherwise you can end up trying to call WriteFile for a handle corresponding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;to the keyboard end point.&lt;/p&gt; &lt;p&gt;(필자요약: 질문자의 답글인데 키보드 top-level collection(최상위 모음) 에 REPORT ID 를 추가할때 어쩌구 저쩌구 얘기가 나온다. 그리고 usage 라는 말도 나온다. 필자가 원하는 답이 여기에 있을 것이라고 생각하여 엄청난 검색을 통해 알게되었는데 원하는 답은 아니었다. 단지, top-level 의 개념은 중요했다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 앞에서 어떤사람이 한 질문과 똑같은 질문인듯 싶다. 왜 도대체 마우스로 인식이 안되냐.. 이 질문이다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;다음은 중요한 개념중에 하나인 Top-Level Collection 이다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Special Top-Level Collections (Reserved for OS use)&lt;/p&gt; &lt;p&gt;Certain HID top-level collections generate a special HID device string. In Windows 2000, Windows XP, and Windows&lt;/p&gt; &lt;p&gt;Server 2003, the top-level collections listed in Table 6 are special cased and each has an additional hardware ID.&lt;/p&gt; &lt;p&gt;Table 6 identifies these collections. The last column identifies the additional string that is added to the hardware&lt;/p&gt; &lt;p&gt;ID list.&lt;/p&gt; &lt;p&gt;Table 6: Special-Cased Top-Level Collections&lt;/p&gt; &lt;p&gt;Device Type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page &amp;nbsp; &amp;nbsp;Usage ID &amp;nbsp; &amp;nbsp; &amp;nbsp; Additional Hardware ID&lt;/p&gt; &lt;p&gt;Pointer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x02 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Joystick &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x04 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&amp;nbsp;&lt;/p&gt; &lt;p&gt;Game pad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;Keyboard &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x06 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;Keypad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x07 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;System Control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer Audio Control &amp;nbsp; &amp;nbsp; 0x0C &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(필자요약: 이게 모냐면 Top-Level Collection 이라 불리우는 입력장치유형이다. 위에서 Usage Page 와 Usage ID 라는 것이 있는데 이게 바로 Report Descriptor 에 있는 항목에 적혀있다. 이걸 어떻게 바꾸느냐에 따라서 가상장치가 마우스가 되느냐, 키보드가 되느냐 아니면 조이스틱이 되느냐를 결정한다. 멋지지 않은가? 물론, 원하는 해답은 아니다. 그러나 필수적으로 개념을 갖고가야 한다. 여기서 중요한게 있다면 입력 장치의 형태가 공유(share)모델이냐 아니면 베타적모델(독점)이냐 이다. 마우스와 키보드는 독점모델이다. 즉, 마우스와 키보드는 장치가 열려있으면 다른 프로그램이 장치를 열어서 쓰고읽는 것이 불가능 하도록 secure 모델로 처리되어있단다. 이때, 이걸 피해가려면 새로운 장치를 동일하게 하나더 만들어서 그 장치와 통신하면 이런 독점모델을 피해갈 수 있단다. MSDN 에 다 나와있다.. 전부 다~ 링크가 있었는데 FireFox 가 깨져서 다 날아가 버리는 바람에 찾을수 없지만 베타적오픈과 공유오픈이 가능한 표시가 위의 Top-Level Collection 에 일일이 나열되어 있는 정보도 찾을 수 있었다. 어쨌거나 중요한건 짚고 넘어가자.. 참고로 잊지는 않았겠지? 가상장치가 일반장치로 인식되서 마우스 장치로 인식시키려고 뻘짓하다가 이런곳까지 당도하게 된거란 점.. 이렇게 정보들을 다양한 방법으로 얻어서 공부하는데도 웹서핑한다고 눈치주는 경우도 있다. x같은 경우지.. 이게 단순히 노는걸로 보여? 입에서 욕나오네.. 갑자기 머리에 히터가 작동되서 한번 지껄여봤습니다. 다시 집중모드로 돌아가봅시다.. ㅋㅋ)Table 13-1 &amp;nbsp; HIDCLASS-Compatible ID for Each Supported Usage지원되는 HIDCLASS 호환 아이디.. HIDCLASS 는 각 장치로 분배를 해주는 역할을 한다고 합니다. 더 자세한건 묻지마삼 다칩니다요.. 전 아는것만 얘기할 뿐임..&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Usage Page &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Usage &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Compatible ID&lt;/p&gt; &lt;p&gt;Generic desktop &amp;nbsp; &amp;nbsp; &amp;nbsp; Pointer or mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_MOUSE&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard or keypad &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_KEYBOARD&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Joystick or game pad &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (Any) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Report Descriptor Header&amp;gt;&lt;/p&gt; &lt;p&gt;앞서서 XBCD 라고 XBOX 조이스틱 에뮬레이션 드라이버에 대해서 말한적이 있습니다.&lt;/p&gt; &lt;p&gt;헤더의 USAGE_PAGE 를 잘 봅시다. 그리고 USAGE 를 봅니다.&lt;/p&gt; &lt;p&gt;// XBCD 예&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;lt;-- 요건 뭐시냐? Table 13-1 입니다욤..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- 위의 Table 6 에 Joystick 의 Usage ID 보입니껑?&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;// vhidmini.h 의 맨마지막 주석이 되어있었던 마우스예제 헤더&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp;DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Generic Desktop), &amp;nbsp; &amp;lt;-- Table 13-1 일반 데스크탑&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- Mouse 임&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- REPORT_ID 꼭 이게 값이 있는지 확인해야함.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID Tool 이라는 놈은 이 값을 빼고 보여줌.(주의!)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Logical Minimum (0),&lt;/p&gt; &lt;p&gt;여기서 Top-Level collection 이 지칭하는 의미는 상위장치입니다. 이런식으로 다중 인터페이스를 구현할 수 있는데 예를들면 마우스와 키보드를 가상장치 하나로 일타쌍피도 만들어낼 수 있습니다. 시중에 파는 키보드 중에 마우스도 있고 USB 포트도 달려있는 키보드들은 이런 다중인터페이스를 만들기위해서는 multiple top-level collection 지정을 해줘야 한다는 얘기죠. 어쨌거나.. 이러한 정보들은 얻었고 Report Descriptor 가 잘못된 것인가라고 판단해보니 전혀 아니었습니다. 오히려 첫번째 XBCD 의 헤더모습에서는 REPORT ID 가 보이지 않는데 두번째 vhidmini.h 에서는 REPORT ID 항목도 빼먹지않고 넣었고 완벽합니다. 그런데 왜.. 대체 왜!! 인식이 마우스로 되지않고 일반장치라고 잡히는 거냐 이말이죠.. 심지어는 공식사이트에서 다운로드 받은 마우스와 키보드 Report Descriptor 를 가져다가도 해봤고 직접 하드웨어에서 뽑아낸 값을 통해서도 해봤지만 모두 인식이 안되었답니다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;사실.. 위에서 언급한 내용은 탐색과정에서 추가로 얻어내는 개념들에 대해서 비중이 있었기에 설명을 하였습니다. 아마, 계속해서 같은 방식으로 설명하면 이 문서를 보면서 쌍욕을하게 될지도 모르기에 후다닥 빨리 접겠습니다. 다음은 제가 문제해결(일반장치를 마우스로 인식하게 만드는)을 하기 위해서 찾아다녔던 링크입니다. 더 많지만 추려서 올려봅니다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&quot; target=&quot;_blank&quot;&gt;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&quot; target=&quot;_blank&quot;&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&quot; target=&quot;_blank&quot;&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&quot; target=&quot;_blank&quot;&gt;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&quot; target=&quot;_blank&quot;&gt;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(결정적인 영감을 주게된 링크는 바로 다음의 링크이고 사실, 앞에서 한번 언급했었던 링크입니다.. 정확히 말하자면 해결방법을 직설적으로 말해준게 아니라, 넌 이걸 이해해야된다라고만 코드의 일부분을 언급하고 숫가락으로 떠먹여 주지는 않겠다는 인상을 풍기는 답글이지요.. 처음에는 이걸 보고도 잘 이해를 못합니다. 저만 그런건 아닐겁니다. 어떤 질문자 중에서는 프린터, 스캐너, 스마트카드를 비롯해 각종 디바이스 드라이버를 만들었다는 이력을 밝히며 저와 같은 증상때문에 고민을 하고 있는 사람도 있었으니까요.. 제가 볼때 이건 MS 의 함정입니다. 의도하지 않은 함정말입니다.)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.osronline.com/showthread.cfm?link=138652&quot; target=&quot;_blank&quot;&gt;https://www.osronline.com/showthread.cfm?link=138652&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;바로 이 답글이 눈을 뜬 사람에게만 통하는 핵심인 셈입니다.&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 22 Jul 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 38&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; .......&lt;/p&gt; &lt;p&gt;(필자요약: 다음의 소스코드와 ReadDescriptorFromRegistry 함수를 봐라.. 너는 이걸 이해해야할 필요가 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 라고 말하며 일부 소스를 첨부했습니다. 그리고는 아무런 추가의 말도 없습니다. 장난하는것도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니고.. -_-; 이때 아차하고 생각을 떠올리면 이 문제는 해결됩니다. 위에서 숱하게 질문하던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 외국 개발자들도 결국에는 알아냈겠지요?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;vhidmini 드라이버를 구동시키고 일반 HID 장치로 인식된 드라이버를 마우스 장치로 둔갑시키기 위해서는&lt;/p&gt; &lt;p&gt;소스를 수정해야 합니다. 바로 vhidmini.c 드라이버 소스를 수정하는 일입니다. 그것도 필자가 생각했었던&lt;/p&gt; &lt;p&gt;Report Descriptor 의 오류를 수정하는 것이 아니라 코드를 수정해야 합니다. 앞에서도 한번 언급했었지만&lt;/p&gt; &lt;p&gt;Microsoft 사의 공식 DDK 샘플소스에 오류가 있을리는 없으니까요. vhidmini.h 에 주석으로 정의되어있던&lt;/p&gt; &lt;p&gt;마우스 Report Descriptor 의 예는 오류가 없었습니다. 오류에 빠지도록 만든것은 바로 ReadDescriptorFromRegistry&lt;/p&gt; &lt;p&gt;함수에 있었습니다. vhidmini 소스를 보면 주석에 써있기를 우리는 하드코딩을 하였다라고 적혀 있습니다.&lt;/p&gt; &lt;p&gt;Report Descriptor 를 하드코딩 하였다는 것이지요. 그런데, 단순히 그냥 하드코딩으로 놔두지.. 더 많은걸&lt;/p&gt; &lt;p&gt;보여주고 싶었던지 if-else 로 두가지 처리루틴으로 나눠놓은것이 문제의 핵심이었던 것입니다. 다음의&lt;/p&gt; &lt;p&gt;소스를 보십시오.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;[vhidmini.c 소스에서 수정해야 할 부분]&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;HID Report Descriptor 를 레지스트리에서 읽어들이는 코드를&lt;/p&gt; &lt;p&gt;&amp;nbsp;하드코딩쪽으만 처리하도록 수정함.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject); &amp;nbsp;// 함정이 발생하는 지역&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 장치를 설치할때 INF 파일에 있는 Report Descriptor 가 레지스트리에 기록되고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분에서 레지스트리에 기록된 Report Descriptor 를 읽어들임.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 그러므로 백날 헤더의 Report Descriptor 를 바꿔봤자 INF 파일에 있었던 것을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 읽어들이는 꼴이 되므로 항상 &amp;quot;일반 HID 장치&amp;quot;(Generic HID Device) 가 드라이버로&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 등록될 수 밖에 없었던 것이다. 이런 제길.. 이 문제로 이틀을 꼬박 다 날렸다니..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Microsoft 는 반성하라~!! Microsoft 는 함정을 제거하라~!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 고로 이 부분으로 빠져들지 않도록 주석처리 하라..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;else{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We will use hard-coded report descriptor.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = DefaultReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Using Hard-coded Report descriptor\n&amp;quot;));&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;case IRP_MN_REMOVE_DEVICE:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // free memory if allocated for report descriptor&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분도 주석처리해야 한다. 왜냐면 레지스트리에서부터 읽어들이지 않았기 때문에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 메모리 할당이 안되어 있기 때문이다. 그냥 두어도 상관없을거 같지만 메모리 해제부분이니&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 꺼림칙하므로 되도록이면 제거하길 바란다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(deviceInfo-&amp;gt;ReadReportDescFromRegistry)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ExFreePool(deviceInfo-&amp;gt;ReportDescriptor);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; SET_NEW_PNP_STATE(deviceInfo, Deleted);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ntStatus = STATUS_SUCCESS; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; break; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이제 vhidmini 샘플을 컴파일하고 VMware 에 vhidmini.sys 와 vhidmini.inf 파일을 복사하자. 그리고 devcon 명령으로 앞서했던 것처럼 install 을 해보자. 설치를 하고나면 장치관리자의 기존에 있던 &amp;quot;HID 준수장치&amp;quot; 라는 것은 없어지고 마우스항목에 &amp;quot;HID 규격 마우스&amp;quot; 가 추가되는 것을 볼 수 있을 것이다.(ㅎㅎ 이맛을 보려고.. 밤을새고 삽질을..) 이제.. 장치관리자에서 새로 추가된 &amp;quot;HID 규격 마우스&amp;quot; 를 선택한 뒤에 속성을 보자. 속성을 선택한 뒤 &amp;quot;자세히&amp;quot; 라는 것을 클릭한다. 그리고 장치인스턴스 ID 라는 것을 보라. HID\MyVirtualHidDevice&amp;amp;Col01 라고 되어있는 것을 볼 수 있다. 또한, 일치하는 장치 ID 를 선택하면 hid_device_system_mouse 라고 되어있다. 즉, 마우스로 인식이 되었다는 것이다. 가상 HID 디바이스 위에서 마우스 장치가 인식되어 있는 것이다. 이제 가상 HID 디바이스와 어플리케이션 간에 통신루틴을 프로그래밍하고 어플리케이션의 명령에따라 상위 클래스로 IRP/URB 같은 요청을 (이거참.. 이 레이어에서는 어떤 요청을 사용해야하는 건지 또 공부해야하는군.. -_-; USB 강의 문서에 보면 상위 클래스는 URB 통신을 한다고 나와있었다..) 날려주면 키보드나 마우스 같은 장치들을 에뮬레이션 시킬수 있다. 곧, 가상장치를 조종할 수 있다. 하지만? 그리 쉽지는 않을 것이다. vhidmini 샘플에는 testvhid 라는 어플리케이션 소스도 같이 들어있는데 이 testvhid 소스는 어플리케이션단에서 vhid miniport 드라이버와 통신하는 예제이다. 참고로 아무런 수정없이 샘플만 컴파일해도 어플리케이션과 드라이버 사이에 제대로 통신이 이루어지지않는다. 역시나 이 문제는 HID Report Descriptor 의 데이타의 구성문제에 속한다. 한번 고생한 것이 또다시 반복되는 시점이기도 하다. 이 부분을 해결하면 어플리케이션은 2 또는 3 가지의 top-level collection 중에서 사용자정의(User-Defined) 콜렉션을 통해서 miniport 드라이버와 통신을 할 수 있게되고 이 통신에 따라서 마우스 IRP 를 상위 클래스로 때려주면 된다. 더 자세한 내용은 스스로 연구하길 바란다. 이상으로 이번문서를 마무리하려고 한다. 왜냐면 이제 테스트 기반이 마련되었으니 나머지 추가구현은 스스로가 해야할 몫이기 때문이다. 어떠한 목적으로 개발하던간에 그 이상은 이제 필자가 관여할 부분이 아닌것 같다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어차피 이 문서의 목적은 가상 마우스를 제작하는 것을 중점으로 삶는 것보다도 모르는 분야를 독학하며 개척해 나갈때 자신의 공부스타일의 한 예로써 제시하는 것이었다. 여기서 거론된 공부스타일을 종합해 본다면 이렇게 말할 수 있을것 같다. &amp;quot;관례를 찾아냄으로써 DIFF 를 추출해내는 공부법&amp;quot; 이라고 할 수 있다. 즉, 최대한 많은 자료들을 검색으로 긁어모은 뒤에 분리분석 작업을 통하여 동일한 부분의 반복을 찾아낸다. 찾아낸 반복내용이 있다면 결국 그 반복은 해당 프로그래밍의 관례에 속한다. 즉, 해당 관례는 몸으로 빨아들이고 차이가 나는 지점에서 기술을 흡수한다. 이런식의 반복학습을 통하여 더이상 다른 코드나 정보들을 찾아낼 수 없다고 판단이 들때 그 기술은 자기것이 된다. 필자는 유저레벨을 공부할때 항상 이방식을 택해왔다. 정보가 고갈되고 더이상 찾아낼수 없을때까지 긴시간을 할애해서 리서치를 먼저 한다. 그 뒤에 코딩으로 들어간다. 그리고 관례코드를 따른다. 그렇게되면 생전 처음보는 프로그래밍에서도 어느지점은 건드려도 되고 어느지점은 절대 건드려서는 안되는지 쉽게(? 정확히가 맞겠다) 익힐수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제는 커널레벨 공부를시작하면서 이 고통스럽고도 지루한 공부방식을 다시 사용하고자하며 다른 사람에게 조그마한 도움이 되고자 이런 문서를 작성하였다. (같이 게임에 미쳐서 광랩하던 친구가 갑자기 URL 을 려줘서 읽어 보았더니 국가에서 인증한 기술이라는 자랑스런 인증서와 함께 뭔가를 팔고있었다. 보란듯이 대놓고 말이다. 디자인도 쌈빡해서 사고싶게 만드는 그것.. 그게 뭔지는 대충 말안해도 알겠지만.. 이 문서를 빨리 공개해야하겠다는 생각이 들었다. 원래는 문서를 다 작성해놓고도 공개하지않는 방향으로 생각을 굳혔다가 아무래도 생각이 바뀌기 시작하였다. 그 이유는 뒷부분의 부록을 보라..) 아마 이 방식으로 공부하는 사람들이 많겠지만 그렇지 않을수도 있을 것이다. 적어도 이렇게 공부할땐 뼈를 깎듯이 힘들지만 원하고자 하는 지식을 얻으면 그 지식의 깊이가 뼈속으로 스며들 것이다. 필자처럼 어떤 새로운 분야에 공부를 시작하거나 공부하는 방법을 몰라서 물어보려는 사람들이 있다면 이 문서를 읽어보라고 말하고 싶다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;잡설&amp;gt;&lt;/p&gt; &lt;p&gt;필자가 만약에 커널디버깅을 잘 다뤘다면 아마도 쉽게 문제를 해결했을지도 모르겠다. 하지만 필자는 귀차니즘 때문에 커널디버깅을 좋아하지 않았고 결국, 공부도하지 않았다. (요즘들어 먹고 살라니.. 공부중이다.. -_-;) 그런데 필자는 오히려 디버거를 쓰지 않으면 않을수록 프로그램에 대한 이해도는 높아진다고 생각한다. 왜냐면 사람의 머리는 충분히 상황을 시뮬레이션 할 수 있다고 생각하기 때문이다. 에뮬레이션은 불가능하겠지만 시뮬레이션은 가능하다. 그리고 이 작업을 통해서 문제가 발생되는 지점을 캣치할 수 있다고 생각한다. 그렇게 되었을때 남보다 더 느릴지 몰라도 이해도는 훨씬더 깊이있는 굴곡을 생성해낸다고 생각한다. 어쩌면 그렇게 믿고싶은 것일지도 모르겠다. 적어도 자신은 그렇게 소신을 갖고있다. 그렇다고 커널디버깅을 배우는 것을 말리거나 도외시하라는 것은 절대 아니다. 필수적으로 갖고가야할 기술이라는 점에는 변함이 없지만 두가지를 모두 안배하는 것이 스스로에게 좀 더 풍요로운 지식을 가져다 줄 것이라는 점을 인지했으면 좋겠다는 의미이다. &amp;quot;Art of Hooking&amp;quot; 이라는 문서처럼 스스로의 깨달음을 전달하려고 쓴 문서는 아니지만 이 시간에도 같은 문제로 삽질하고있을 그들에게(아직도 정확한 답변을 보지 못한 질문자들이 인터넷에 깔려있음을.. 이미 보여줬다..) 이틀이라는 시간을 좀 더 귀중한 곳에 쓸 수 있도록 해줄 수 있다는 것은 행복한 일이라고 생각한다. 만약 누군가에게 이런 도움을 지속적으로 받을수 있었다면 본인은 솔로여야할 이유가 없었을 것이리라.. (아쉽게도 영어를 못하니 국내만이라도 도움을 받으면 좋을듯 싶다.) 참고로.. 이 문서는 주제를 인지하는 시점부터 해결과정을 도출해내는 모든 전 과정이 거의 실시간으로 쓰여졌다.. 그렇게 해야만이 이 문서의 목적인 &amp;quot;가상마우스&amp;quot; 와 &amp;quot;공부방법론&amp;quot; 두가지를 모두 전달할 수 있다고 판단했기 때문이다. 필자는 누군가 이 문서를 읽고 얻은게 있었다면 그것만으로 행복할 것이다. 하드에 처박혀 쓰레기가 된채 어느날 자신도 모르게 삭제되는 그런 정보가 아니라는 점만으로도 충분히 가치있는 것이니까..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록1: 필자가 생각하는 에뮬레이션과 시뮬레이션의 차이점]&lt;/p&gt; &lt;p&gt;에뮬레이션: 기계의 톱니바뀌처럼 구성요소들의 기능자체들이 모두 동일하게 작동해야 한다. (기능/작동의 동일화)&lt;/p&gt; &lt;p&gt;시뮬레이션: 기능자체를 동일하게 할 필요없이 입/출력되는 수치/값만 동일하면 된다. (수치/데이타의 동일화)&lt;/p&gt; &lt;p&gt;(필자주: 틀렸을 수도 있다. 정확하지않다. 다만, 여태까지 몸으로 와닿는 느낌자체를 말로 풀어써본 것 뿐이다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록2: 시중에 떠도는 물리형 Auto Mouse 탐지법]&lt;/p&gt; &lt;p&gt;먼저, 가상장치에 대한 것부터 언급해보고 물리형으로 넘어가겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;1. 가상장치 탐지방법&amp;gt;&lt;/p&gt; &lt;p&gt;재밌는 사실이 있는데 아는 사람은 알 것이고 모르는 사람은 모를 것이다.&lt;/p&gt; &lt;p&gt;MSPRESS 에 보면 짜가장치(FakeDevice) 탐색법이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;HANDLE CtestDlg::FindFakeDevice()&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; GUID hidguid;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; HidD_GetHidGuid(&amp;amp;hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; CDeviceList devlist(hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; int ndevices = devlist.Initialize();&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; for(int i = 0; i &amp;lt; ndevices; ++i)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HANDLE h = CreateFile(devlist.m_list[i].m_linkname, 0,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FILE_SHARE_READ | FILE_SHARE_WRITE,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(h == INVALID_HANDLE_VALUE)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HIDD_ATTRIBUTES attr = {sizeof(HIDD_ATTRIBUTES)};&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;BOOLEAN okay = HidD_GetAttributes(h, &amp;amp;attr);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CloseHandle(h);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(!okay)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(attr.VendorID != HIDFAKE_VID ||&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; attr.ProductID != HIDFAKE_PID)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return CreateFile(devlist.m_list[i].m_linkname,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GENERIC_READ | GENERIC_WRITE, 0, NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; return INVALID_HANDLE_VALUE;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;위의 짜가장치 탐색법은 골때리게 단순하다. 결국에는 HIDFAKE_VID 와 HIDFAKE_PID 를 체크하는 개념이다. 즉, 제작사(Vendor ID)와 제품번호(Product ID)를 가지고 짜가인지 판별하겠다는 개념이다. 그렇다면 제작사와 제품번호는 속일수 없다고 생각하는가? 커널을 뒤짚어 엎는(Subvert) 판국에 저렇게 단순하게 비교해서는 가상장치를 막을수 없다. 위의코드를 보고 판단을 하길 가상장치는 다 막겠다고 판단한다면 정말 큰일이다. 어처구니 없는 싸움이 키보드보안이래 또 발생할 것이기 때문이다. 위의 코드가 의미하는 바를 잘못해석하면 안된다. 위의 코드는 이렇게 해석해야 한다. 그 어떠한 가상장치를 막을수 있다는 컨셉하에 위의 코드를 만들길 시도한것이 아니라 고정장치를 알아내기위해 만들어진 컨셉이라는 점을 말이다. 단지 정형화 되어있는 즉, 고정되어있는 상태에서는 가능할 수 있겠다. 이해를 돕기위해 예를한가지 들어보자. VMware 같은 가상머신 안에서 작동하는 것인지 정도는 파악할 수 있지 않을까 싶다. 왜냐면 VMware 가 동적으로 제작사와 제품번호를 바꿔야할 까닭이 없지않은가? 다르게 말하면 VMware 가 굳이 자기 제품정보를 굳이 속이거나 변덕스럽게 수시로 바꿔야할 필요가 전혀 없다는 얘기다. 이런경우에는 마치 하드웨어처럼 고정장치로 봐도 무방하다. 고로 VMware 에는 항상 고정된 장치가 있다고 판단해도 될 것이며 VMware 안에 구현된 장치들 중에는 가상장치들이 있으므로 항상 디텍트 할 수 있단 얘기가 되므로 위의 짜가장치 탐색법은 그러한 경우에 사용할 수 있는 컨셉이라는 소리다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아직 더 깊이 연구해보지는 않았지만 가상장치와 전쟁을 선포할 경우에 또 하나의 &amp;quot;키보드보안&amp;quot; 같은 파국으로 치닫기에 좋은 스토리가 탄생할 것이다. 차라리 이것을 좀 더 유용한 곳에 사용해보면 어떨까? 바로!! 물리형 Auto Mouse 를 탐지하는 것이다. 기술은 적합한 곳에 쓰라고 있는 것이지 말도안되는 헛다리 싸움에 쓰라고 존재하지 않는다. 기술을 적용시킬때는 단순히 눈과 머리로만 판단하지말고 포괄적인 정황을 바탕으로 자신의 가슴속에 확신이 설때 비로소 본격적인 전쟁에 들어가야 한다. 그저 돈이된다고 키보드보안처럼 너도나도 발담궈놓고 아무도 책임지지않고 아무도 발도 못빼는 승자없는 싸움에 휘말리기 싫다면 필히 이 말을 웃어넘기지 말아야 할 것이다.(아마, 이젠 더이상 발을 빼지도 못할것이다.. 담구지 말라고 뜯어말려도&lt;/p&gt; &lt;p&gt;담궜으니 해야할 일은 그저 땜빵밖에 뭐가 더 있겠는가.. ㅉㅉ)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;2. 물리형 Auto Mouse 탐지&amp;gt;&lt;/p&gt; &lt;p&gt;물리형 Auto Mouse 를 탐지하는 것의 기본바탕은 앞서 짜가장치 탐색에 사용된 코드를 그대로 채용하면 되겠다. 단, 제작사와 제품번호만이 아닌 추가정보를 이용할 필요가 있겠다. 그런데, 왜 효용성이 물리형 Auto Mouse 를 탐지하는 것에 효력이 있을까? 그 이유는 간단하다. 다음과 같은 정보를 보자. 필자는 최근에 오픈된 MMORPG 온라인 게임의 Auto Mouse 를 구매해보았다. 과연 어떻게 돌아가는지 궁금증도 있었고 진짜 완벽하게 구동이 되는것인지 두눈으로 확인해보고 싶었기 때문이었다. 그런데 일단, 한군데의 제품은 구동이 제대로 안되는 것을 확인하였다. 다만, 마우스 입력이나 키보드 입력은 그대로 게임속으로 전달되고 있다는 점에 주목하였다. 과연 그러한 것을 어떻게 탐지해낼 수 있을까? 다음은 USB View 라는 프로그램으로 Auto Mouse 장치의 Descriptor 를 본 화면이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Auto Mouse HID Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;quot;USB Composite 장치&amp;quot;&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x0200&lt;/p&gt; &lt;p&gt;bDeviceClass: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x20 (32)&lt;/p&gt; &lt;p&gt;idVendor: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x03EB (Atmel Corporation)&lt;/p&gt; &lt;p&gt;idProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x4743&lt;/p&gt; &lt;p&gt;bcdDevice: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x1000&lt;/p&gt; &lt;p&gt;iManufacturer: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY&amp;quot;&lt;/p&gt; &lt;p&gt;iProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x02&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY PRO8&amp;quot;&lt;/p&gt; &lt;p&gt;iSerialNumber: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x03&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;1.0.0&amp;quot;&lt;/p&gt; &lt;p&gt;bNumConfigurations: &amp;nbsp; 0x01&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;그렇다. idVendor 가 제작사이고 idProduct 가 제품번호이겠다. 이 정보는 필자가 예상컨대 고정이라 할 수 있다. 일단, 텍스트를 주의깊게 보자. &amp;quot;Atmel Corporation&amp;quot; 이 보이는가? 해커들이 가장 많이 사용한다는 그 유명한 &amp;quot;Atmel&amp;quot; 칩이 사용되었다. 일명 FPGA 칩이라고 불리운다. 이 FPGA 칩은 프로그래밍 가능한 이점이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(사견: 언제부터 마우스가 Atmel 칩으로 제작되었던가? 그래서 오토마우스가 그리도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;비싼거였나보다.. 싸구려 PIC 칩만으로도 마우스를 만들수 있다. 전자업계는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;원래 원가전쟁을 벌이는 계통이라서 단 1원이라도 원가를 절감해 보려고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;깎고깎고 전쟁을 벌인다. 필자의 친구가 전자회사 CEO 라서 이점은 매우 잘&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;알고있다. 그 친구의 말을 빌어보자면 진짜 1원갖고 쪼잔하게 굴 수 밖에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;없다고 한다. 살아남아야 하니까 말이다.. 그런데 FPGA 칩을 쓰는 것을 보면&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좀 수상하다. 왜 재프로그래밍이 가능한 칩을 쓰는 것인가.. 재수없으면 기타장치&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;메모리스틱 리더기같은 것들이 연결되어 있을수도 있으므로 함부로 판단하기는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이르지만 아마도 대량유통되는 칩이 아닌 DIY(사제품)칩을 쓴다는 것은 기정&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;사실이라고 추측할만 하지않은가? 필자가 대에충 찾아보니 Auto Mouse 제작사&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;두군데가 Atmel 칩을 사용하고 있었다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;만약 이 Atmel 칩이 필자가 아는 것과 달리 재프로그래밍이 가능한 기능이 없다면 게임업계에서는 대박의 찬스를 잡은 것이리라.. 왜? 고정이잖은가? 고정!! 또, 재미난 정보를 볼 수 있는데 바로 그 유명하다고 하는 &amp;quot;ATPLAY&amp;quot; 라는 마크가 찍혀있다. 아주 그냥 상호를 갖다가 박아놓은거보니 장사할 생가이 없다하겠다.&lt;/p&gt; &lt;p&gt;일단, 칩이 Atmel 칩으로 제작되어있는 USB 형 물리장치들을 사용하는 사용자는 모두 감시대상순위로 집어넣어도 십중팔구는 맞아떨어질 것이다. 특히나 Atmel 칩에 상관없이 상호명 ATPLAY 가 박혀있다면 그 사용자는 거의 Auto Mouse 를 사용하고 있을 확률이 99.9% 라고 할 수 있겠다. 그리고 USB View 같은 프로그램이 사용하는 루틴들은 위에서 언급된 루틴들에서 크게 벗어나지는 않을테니 쉽게탐지할 수 있다고 감히 추측해본다. 딱한가지 우려되는 사항이 있다면 프로그래밍 가능한 칩이기 때문에 업데이트 기능으로&lt;/p&gt; &lt;p&gt;펌웨어를 갈아치울 경우에 난감하게 될 것이다. 하지만 방금 언급한 방식을 사용한다면 Auto Mouse 제작사의 미래고객이 아닌 현재 고객들은 99.9% 가 탐지된다고 봐도 무방할 것이다. 물론, Auto Mouse 의 종류별로 이짓을 해야겠지만.. 프로그래머들의 습성상 모두 식별자를 기록해놓았을테니(아마, Atmel 칩에 코딩을 의뢰하거나 혹은 Atmel 칩에 프로그램이 가능한 사람을 영입했겠지만 프로그래머들이 그런거 생각안한다. 왜냐면 원리원칙을 따르려는 프로그래머의 심리상 바보같이 위에처럼 ATPLAY 를 박는게 미덕으로&lt;/p&gt; &lt;p&gt;생각할 것이기 때문이다.) 행동만 빨리 취한다면 현재 Auto Mouse 사용자들의 태반은 모두 다 탐지해낼 수 있을 것이라고 감히 판단해본다. 즉, 물리형은 고정이라는 변수를 잘 활용할 수 있기에 탐지도 비교적 수월한 편에 속한다는 것이다. 한가지 더 재미난 상상을 해보자.. 과연 Auto Mouse 업체에서 펌웨어 업데이트 기능을 추가로 만들어내는데 얼마나 시간이 걸릴까? 누가 더 대응이 빠를까..? 과연 이 전쟁에서 Auto Mouse 업체의 대응이 빠를까? 아니면 막는자의 대응이 더 빠를까? 아마도 덩치가 작은쪽이 더 빠르겠지만 두고볼 일일 것이다. 이 전쟁은 어느한쪽의 시간전쟁일 뿐이다.. 정확하고 빠른판단이 내려지면 그대로 바로 행하는 쪽이 이기는 것이다. 현재로써 본 필자의 생각으로는 물리형 Auto Mouse 는 막을 수 있다. 이 문서가 나온 시점 앞으로가 문제이다.. 점차 Auto Mouse 는 가상마우스로 진화를 꿈꾸고 있기 때문이다. 그것이 바로 기술의 대세인 것이다. 오늘의 기술이 내일의 쓰레기가 되어버리는 시대에서 속도전의 중요함이다. 승자는 과연 누가 될까? 아무도 모른다.. 기술은 끝이 없으니까.. 마이 골치아픈 것이다.. -_-; 어디까지나.. 필자 개인이 현 상태를 진단해본 사견일 뿐이다. 이 이상 어케 더 판단하랴..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[HID Descriptor Tool]&lt;/p&gt; &lt;p&gt;USB.ORG 공식 사이트에서 받을수 있음&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&quot; target=&quot;_blank&quot;&gt;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(위에서 언급한 사이트 이외 참고한 사이트)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/485&quot; target=&quot;_blank&quot;&gt;http://kkamagui.tistory.com/485&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.keil.com/forum/docs/thread13037.asp&quot; target=&quot;_blank&quot;&gt;http://www.keil.com/forum/docs/thread13037.asp&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;000096&amp;quot;. Is it possible to get the SymbolicLinkName&lt;/p&gt; &lt;p&gt;instead?&lt;/p&gt; &lt;p&gt;If someone could help...&lt;/p&gt; &lt;p&gt;Thanks, Roger&lt;/p&gt; &lt;p&gt;(필자요약: HID 인터페이스를 노출하는 USB 장치를 만들었다. 그런데 그게 마우스나 키보드가 아니네? 단지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;일반 HID 장치인거야. 디바이스 디스플레이에 보면 &amp;quot;HID-compliant device&amp;quot; 라고 표시되네.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;횽님들.. 알려주십쇼.. 뭐 이런 내용식으로 글을 써놨다. 그래도 아는게 많은 사람이라서 그런지&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;정보들을 많이 뿌려놨는데 독이되는 요소들이 있지만, 덤으로 알게되는 요소들도 그 못지않게&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;많다. IOCTL_HID_SET_FEATURE 과 IOCTL_HID_GET_FEATURE 에대한 얘기는(추후 구현되어야 하는 내용)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좋은 정보임에 틀림없다. 그런데 우리가 원하는 답을 얻지는 못하고 단지 INF 파일에 VID 와&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PID 스트링이 문제의 시발점이 될수도 있지는 않은가 하는 의심을 해볼수 있다. 물론, 그게 해답은&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;아니지만 추가정보를 검색해야할 키워드로써 대상물망에 넣어두자. VID 란 벤더아이디를 의미하고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;제작사의 고유식별번호이며, PID 란 프로덕트 아이디 즉, 제품번호이겠다. 이게 하드웨어는 모두&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;고유하다고 하는데 과연 이 때문에 마우스나 키보드로 인식이 안되고 일반장치로 인식되는 것일까?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;when are you trying to open a handle? during AddDevice or&lt;/p&gt; &lt;p&gt;IRP_MN_START_DEVICE? neither will work b/c a file create can only occur&lt;/p&gt; &lt;p&gt;once the start irp has come back to the pnp manager. so to make this work i&lt;/p&gt; &lt;p&gt;would&lt;/p&gt; &lt;p&gt;a) register a custom device interface GUID&lt;/p&gt; &lt;p&gt;b) register for device interface arrivals on your custom guid. when you&lt;/p&gt; &lt;p&gt;get called, open your stack like FireFly does&lt;/p&gt; &lt;p&gt;you will also need to register for handle notifications on the file handle&lt;/p&gt; &lt;p&gt;that you open so that you can gracefully disable the device. If you use the&lt;/p&gt; &lt;p&gt;KMDF firefly sample, the WDFIOTARGET object does this for you&lt;/p&gt; &lt;p&gt;(필자요약: 답변중에 하나인데 이 답변은 질문자의 추측보다 더 가관이다. IRP_NM_START_DEVICE 나 AddDevice 등록시 (필자는 커널을 몰라서 몬소린지 모르지만 이건 아니다정도의 감은 있었다.. -_-;) 하라는 식으로 답변이 달려있는데 KMDF 까지 들먹거리는걸로 봐서는 논점에서 많이 빗나갔다. KMDF 는 새로운 드라이버 개발 프레임워크인데 질문자가 그걸 물어본게 아니다. 기존의 방법으로 설명해줘야하는 것이 옳은데 그렇지도 않았고, 너무 많은 작업을 추가하라고 주문하는거보니 필자의 생각과 달랐다. 필자의 감은 Report Descriptor 만으로도 해결될 문제라고 속삭이고 있었기 때문에 이 답은 해결책이 아니었다. 다른 답변중에는 URB 를 보내라는 말도 있었다. 모두 무시한다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;지금 거론하는 필자의 문제해결 방법은 링크를 보여주면서 찾아나가는 방법을 설명하고 있다. 그렇기에 링크역시 필자가 검색해서 누른 순서대로 임을 밝힌다. 다음으로 찾은 것은 MSDN 의 설명이다. 그런데 MSDN 의 설명은 항상 깨달음을 얻은뒤에나 값진 보물이 되지 깨달음을 얻기전까지는 그저 잘 만들어진 명세서에 불과하다고 느낄때가 많다. 마치 선생님이 &amp;quot;공부하라&amp;quot;고 그렇게 들볶던 말들이 성인이 된 뒤에 &amp;quot;정답&amp;quot; 이라고 느끼는 것처럼 느낀뒤에만 알 수 있는 것들이 기록되어 있는게 MSDN 과도 같다. 왜 그땐 몰랐지? 왜 그땐 안봤지? 나중에 이런말 자주하게 될거다. ㅎㅎ 그런데.. 역시.. -_-; 이 링크를 보던 시점(현 글을 쓰는 시점기준으로 하루전)만 해도 이 링크는 그저 도움이 안되었다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa487252.aspx&quot; target=&quot;_blank&quot;&gt;http://msdn.microsoft.com/en-us/library/aa487252.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(필자요약: 설명이 잘 되있다. 읽어보라.. 해결책도 들어있다. 그런데 그냥보면 절대 모른다. 개고생하면 그때는 답이 보이지만 그냥보면 모른다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&quot; target=&quot;_blank&quot;&gt;http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&amp;amp;board_pc2020=driver&amp;amp;id=2986&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 이 사이트는 중국사이트인데 읽을수가 없다. 몇가지 좋은 키워드와 코드가 있는데 해결책은 아니고 나중에 마우스나 키보드를 구현할때 참고할 만한 코드가 아주 조금 있을 뿐이었다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&quot; target=&quot;_blank&quot;&gt;http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=144873&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 필자가 겪는 문제를 어느정도 일부분은 해결한 것 같기도하고 그렇지 않은거 같기도 한데 희한한&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 삽질을 하고 있었다. Descriptor 를 계속해서 바꿔가면서 테스트하는 것을 물어보고 있었다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 마우스와 키보드를 인식시키기 위해서 vhidmini 를 기본베이스로 디스크립터를 조작하는데 설치가&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 안된다는 그런 질문이었다. 질문양이 많아서 짤라붙이기는 못하겠다. 답글을 보자.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Adrian Schlesinger&lt;/p&gt; &lt;p&gt;xxxxxx@baum.ro&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 24 Sep 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 7&lt;/p&gt; &lt;p&gt;RE: Simulate keystrokes&lt;/p&gt; &lt;p&gt;I have detected what was wrong:&lt;/p&gt; &lt;p&gt;1. When adding the report ID item to the keyboard top-level collection, an additional byte should be returned to&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;the system at the beginning of the data, specifying that report ID.&lt;/p&gt; &lt;p&gt;2. Communication from user mode did not work because when cycling through the HID devices,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;in addition to vendor ID, product ID and version, the usage specified for the additional end point should also&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;be matched (with Vendor Usage 1), otherwise you can end up trying to call WriteFile for a handle corresponding&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;to the keyboard end point.&lt;/p&gt; &lt;p&gt;(필자요약: 질문자의 답글인데 키보드 top-level collection(최상위 모음) 에 REPORT ID 를 추가할때 어쩌구 저쩌구 얘기가 나온다. 그리고 usage 라는 말도 나온다. 필자가 원하는 답이 여기에 있을 것이라고 생각하여 엄청난 검색을 통해 알게되었는데 원하는 답은 아니었다. 단지, top-level 의 개념은 중요했다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/hid-minidriver-multiple-report-descriptors-543372/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;(필자요약: 앞에서 어떤사람이 한 질문과 똑같은 질문인듯 싶다. 왜 도대체 마우스로 인식이 안되냐.. 이 질문이다.)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;다음은 중요한 개념중에 하나인 Top-Level Collection 이다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/whdc/archive/HID_HWID.mspx#E1&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;Special Top-Level Collections (Reserved for OS use)&lt;/p&gt; &lt;p&gt;Certain HID top-level collections generate a special HID device string. In Windows 2000, Windows XP, and Windows&lt;/p&gt; &lt;p&gt;Server 2003, the top-level collections listed in Table 6 are special cased and each has an additional hardware ID.&lt;/p&gt; &lt;p&gt;Table 6 identifies these collections. The last column identifies the additional string that is added to the hardware&lt;/p&gt; &lt;p&gt;ID list.&lt;/p&gt; &lt;p&gt;Table 6: Special-Cased Top-Level Collections&lt;/p&gt; &lt;p&gt;Device Type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Usage Page &amp;nbsp; &amp;nbsp;Usage ID &amp;nbsp; &amp;nbsp; &amp;nbsp; Additional Hardware ID&lt;/p&gt; &lt;p&gt;Pointer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x02 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_MOUSE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exclusive&lt;/p&gt; &lt;p&gt;Joystick &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x04 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&amp;nbsp;&lt;/p&gt; &lt;p&gt;Game pad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;Keyboard &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x06 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;Keypad &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x07 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_KEYBOARD &amp;nbsp; &amp;nbsp; &amp;nbsp;exclusive&lt;/p&gt; &lt;p&gt;System Control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer Audio Control &amp;nbsp; &amp;nbsp; 0x0C &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(필자요약: 이게 모냐면 Top-Level Collection 이라 불리우는 입력장치유형이다. 위에서 Usage Page 와 Usage ID 라는 것이 있는데 이게 바로 Report Descriptor 에 있는 항목에 적혀있다. 이걸 어떻게 바꾸느냐에 따라서 가상장치가 마우스가 되느냐, 키보드가 되느냐 아니면 조이스틱이 되느냐를 결정한다. 멋지지 않은가? 물론, 원하는 해답은 아니다. 그러나 필수적으로 개념을 갖고가야 한다. 여기서 중요한게 있다면 입력 장치의 형태가 공유(share)모델이냐 아니면 베타적모델(독점)이냐 이다. 마우스와 키보드는 독점모델이다. 즉, 마우스와 키보드는 장치가 열려있으면 다른 프로그램이 장치를 열어서 쓰고읽는 것이 불가능 하도록 secure 모델로 처리되어있단다. 이때, 이걸 피해가려면 새로운 장치를 동일하게 하나더 만들어서 그 장치와 통신하면 이런 독점모델을 피해갈 수 있단다. MSDN 에 다 나와있다.. 전부 다~ 링크가 있었는데 FireFox 가 깨져서 다 날아가 버리는 바람에 찾을수 없지만 베타적오픈과 공유오픈이 가능한 표시가 위의 Top-Level Collection 에 일일이 나열되어 있는 정보도 찾을 수 있었다. 어쨌거나 중요한건 짚고 넘어가자.. 참고로 잊지는 않았겠지? 가상장치가 일반장치로 인식되서 마우스 장치로 인식시키려고 뻘짓하다가 이런곳까지 당도하게 된거란 점.. 이렇게 정보들을 다양한 방법으로 얻어서 공부하는데도 웹서핑한다고 눈치주는 경우도 있다. x같은 경우지.. 이게 단순히 노는걸로 보여? 입에서 욕나오네.. 갑자기 머리에 히터가 작동되서 한번 지껄여봤습니다. 다시 집중모드로 돌아가봅시다.. ㅋㅋ)Table 13-1 &amp;nbsp; HIDCLASS-Compatible ID for Each Supported Usage지원되는 HIDCLASS 호환 아이디.. HIDCLASS 는 각 장치로 분배를 해주는 역할을 한다고 합니다. 더 자세한건 묻지마삼 다칩니다요.. 전 아는것만 얘기할 뿐임..&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Usage Page &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Usage &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Compatible ID&lt;/p&gt; &lt;p&gt;Generic desktop &amp;nbsp; &amp;nbsp; &amp;nbsp; Pointer or mouse &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_MOUSE&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard or keypad &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_KEYBOARD&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Joystick or game pad &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_GAME&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System control &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID_DEVICE_SYSTEM_CONTROL&lt;/p&gt; &lt;p&gt;Consumer &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (Any) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HID_DEVICE_SYSTEM_CONSUMER&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Report Descriptor Header&amp;gt;&lt;/p&gt; &lt;p&gt;앞서서 XBCD 라고 XBOX 조이스틱 에뮬레이션 드라이버에 대해서 말한적이 있습니다.&lt;/p&gt; &lt;p&gt;헤더의 USAGE_PAGE 를 잘 봅시다. 그리고 USAGE 를 봅니다.&lt;/p&gt; &lt;p&gt;// XBCD 예&lt;/p&gt; &lt;p&gt;char ReportDescriptor[213] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE_PAGE (Generic Desktop) &amp;nbsp; &amp;nbsp; &amp;lt;-- 요건 뭐시냐? Table 13-1 입니다욤..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x09, 0x04, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// USAGE (Joystick) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- 위의 Table 6 에 Joystick 의 Usage ID 보입니껑?&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0xa1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// COLLECTION (Application)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; USAGE_PAGE (Button)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x25, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; LOGICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x35, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MINIMUM (0)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; 0x45, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; PHYSICAL_MAXIMUM (1)&lt;/p&gt; &lt;p&gt;// vhidmini.h 의 맨마지막 주석이 되어있었던 마우스예제 헤더&lt;/p&gt; &lt;p&gt;HID_REPORT_DEscRIPTOR &amp;nbsp; &amp;nbsp;DefaultReportDescriptor[] = {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Generic Desktop), &amp;nbsp; &amp;lt;-- Table 13-1 일반 데스크탑&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x02, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Mouse), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;-- Mouse 임&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Application),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x85, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//REPORT_ID (1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- REPORT_ID 꼭 이게 값이 있는지 확인해야함.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x09, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage (Pointer), &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HID Tool 이라는 놈은 이 값을 빼고 보여줌.(주의!)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0xA1, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Collection (Physical),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x05, 0x09, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Page (Buttons),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x19, 0x01, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Minimum (01),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x29, 0x03, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Usage Maximun (03),&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x15, 0x00, &amp;nbsp; &amp;nbsp; &amp;nbsp;//Logical Minimum (0),&lt;/p&gt; &lt;p&gt;여기서 Top-Level collection 이 지칭하는 의미는 상위장치입니다. 이런식으로 다중 인터페이스를 구현할 수 있는데 예를들면 마우스와 키보드를 가상장치 하나로 일타쌍피도 만들어낼 수 있습니다. 시중에 파는 키보드 중에 마우스도 있고 USB 포트도 달려있는 키보드들은 이런 다중인터페이스를 만들기위해서는 multiple top-level collection 지정을 해줘야 한다는 얘기죠. 어쨌거나.. 이러한 정보들은 얻었고 Report Descriptor 가 잘못된 것인가라고 판단해보니 전혀 아니었습니다. 오히려 첫번째 XBCD 의 헤더모습에서는 REPORT ID 가 보이지 않는데 두번째 vhidmini.h 에서는 REPORT ID 항목도 빼먹지않고 넣었고 완벽합니다. 그런데 왜.. 대체 왜!! 인식이 마우스로 되지않고 일반장치라고 잡히는 거냐 이말이죠.. 심지어는 공식사이트에서 다운로드 받은 마우스와 키보드 Report Descriptor 를 가져다가도 해봤고 직접 하드웨어에서 뽑아낸 값을 통해서도 해봤지만 모두 인식이 안되었답니다.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;사실.. 위에서 언급한 내용은 탐색과정에서 추가로 얻어내는 개념들에 대해서 비중이 있었기에 설명을 하였습니다. 아마, 계속해서 같은 방식으로 설명하면 이 문서를 보면서 쌍욕을하게 될지도 모르기에 후다닥 빨리 접겠습니다. 다음은 제가 문제해결(일반장치를 마우스로 인식하게 만드는)을 하기 위해서 찾아다녔던 링크입니다. 더 많지만 추려서 올려봅니다.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&quot; target=&quot;_blank&quot;&gt;http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2008-01/msg00501.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&quot; target=&quot;_blank&quot;&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0829.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&quot; target=&quot;_blank&quot;&gt;http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2005-03/0806.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/minidriver-hidclass-336914/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&quot; target=&quot;_blank&quot;&gt;http://www.techreplies.com/drivers-43/my-hid-mouse-how-write-data-331146/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&quot; target=&quot;_blank&quot;&gt;http://www.osronline.com/DDKx/intinput/hidfunc_7oky.htm&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&quot; target=&quot;_blank&quot;&gt;https://www.usb.org/phpbb/viewtopic.php?t=14027&amp;amp;sid=b40543b8bc019ff50c70025ff1886898&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(결정적인 영감을 주게된 링크는 바로 다음의 링크이고 사실, 앞에서 한번 언급했었던 링크입니다.. 정확히 말하자면 해결방법을 직설적으로 말해준게 아니라, 넌 이걸 이해해야된다라고만 코드의 일부분을 언급하고 숫가락으로 떠먹여 주지는 않겠다는 인상을 풍기는 답글이지요.. 처음에는 이걸 보고도 잘 이해를 못합니다. 저만 그런건 아닐겁니다. 어떤 질문자 중에서는 프린터, 스캐너, 스마트카드를 비롯해 각종 디바이스 드라이버를 만들었다는 이력을 밝히며 저와 같은 증상때문에 고민을 하고 있는 사람도 있었으니까요.. 제가 볼때 이건 MS 의 함정입니다. 의도하지 않은 함정말입니다.)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://www.osronline.com/showthread.cfm?link=138652&quot; target=&quot;_blank&quot;&gt;https://www.osronline.com/showthread.cfm?link=138652&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;바로 이 답글이 눈을 뜬 사람에게만 통하는 핵심인 셈입니다.&lt;/p&gt; &lt;p&gt;allen zhang&lt;/p&gt; &lt;p&gt;xxxxxx@sina.com&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Join Date: 22 Jul 2008&lt;/p&gt; &lt;p&gt;Posts To This List: 38&lt;/p&gt; &lt;p&gt;RE: VHidMini report descriptor(s)&lt;/p&gt; &lt;p&gt;see the follow source code and the ReadDescriptorFromRegistry function, You should be understand it.&lt;/p&gt; &lt;p&gt;deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;queryStatus = CheckRegistryForDescriptor(DeviceObject);&lt;/p&gt; &lt;p&gt;if(NT_SUCCESS(queryStatus)) {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; .......&lt;/p&gt; &lt;p&gt;(필자요약: 다음의 소스코드와 ReadDescriptorFromRegistry 함수를 봐라.. 너는 이걸 이해해야할 필요가 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 라고 말하며 일부 소스를 첨부했습니다. 그리고는 아무런 추가의 말도 없습니다. 장난하는것도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니고.. -_-; 이때 아차하고 생각을 떠올리면 이 문제는 해결됩니다. 위에서 숱하게 질문하던&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 외국 개발자들도 결국에는 알아냈겠지요?)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;vhidmini 드라이버를 구동시키고 일반 HID 장치로 인식된 드라이버를 마우스 장치로 둔갑시키기 위해서는&lt;/p&gt; &lt;p&gt;소스를 수정해야 합니다. 바로 vhidmini.c 드라이버 소스를 수정하는 일입니다. 그것도 필자가 생각했었던&lt;/p&gt; &lt;p&gt;Report Descriptor 의 오류를 수정하는 것이 아니라 코드를 수정해야 합니다. 앞에서도 한번 언급했었지만&lt;/p&gt; &lt;p&gt;Microsoft 사의 공식 DDK 샘플소스에 오류가 있을리는 없으니까요. vhidmini.h 에 주석으로 정의되어있던&lt;/p&gt; &lt;p&gt;마우스 Report Descriptor 의 예는 오류가 없었습니다. 오류에 빠지도록 만든것은 바로 ReadDescriptorFromRegistry&lt;/p&gt; &lt;p&gt;함수에 있었습니다. vhidmini 소스를 보면 주석에 써있기를 우리는 하드코딩을 하였다라고 적혀 있습니다.&lt;/p&gt; &lt;p&gt;Report Descriptor 를 하드코딩 하였다는 것이지요. 그런데, 단순히 그냥 하드코딩으로 놔두지.. 더 많은걸&lt;/p&gt; &lt;p&gt;보여주고 싶었던지 if-else 로 두가지 처리루틴으로 나눠놓은것이 문제의 핵심이었던 것입니다. 다음의&lt;/p&gt; &lt;p&gt;소스를 보십시오.&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;[vhidmini.c 소스에서 수정해야 할 부분]&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;HID Report Descriptor 를 레지스트리에서 읽어들이는 코드를&lt;/p&gt; &lt;p&gt;&amp;nbsp;하드코딩쪽으만 처리하도록 수정함.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;HidDescriptor = DefaultHidDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Check to see if we need to read the Report Descriptor from&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // registry. If the &amp;quot;ReadFromRegistry&amp;quot; flag in the registry is set&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // then we will read the descriptor from registry using routine&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // ReadDescriptorFromRegistry(). Otherwise, we will use the&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // hard-coded default report descriptor.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = CheckRegistryForDescriptor(DeviceObject); &amp;nbsp;// 함정이 발생하는 지역&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(NT_SUCCESS(queryStatus)){&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We need to read read descriptor from registry&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 장치를 설치할때 INF 파일에 있는 Report Descriptor 가 레지스트리에 기록되고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분에서 레지스트리에 기록된 Report Descriptor 를 읽어들임.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 그러므로 백날 헤더의 Report Descriptor 를 바꿔봤자 INF 파일에 있었던 것을&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 읽어들이는 꼴이 되므로 항상 &amp;quot;일반 HID 장치&amp;quot;(Generic HID Device) 가 드라이버로&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 등록될 수 밖에 없었던 것이다. 이런 제길.. 이 문제로 이틀을 꼬박 다 날렸다니..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // Microsoft 는 반성하라~!! Microsoft 는 함정을 제거하라~!!&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 고로 이 부분으로 빠져들지 않도록 주석처리 하라..&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; queryStatus = ReadDescriptorFromRegistry(DeviceObject);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(!NT_SUCCESS(queryStatus)){ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Failed to read descriptor from registry\n&amp;quot;));&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ntStatus = STATUS_UNSUCCESSFUL;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;else{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // We will use hard-coded report descriptor.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; deviceInfo-&amp;gt;ReportDescriptor = DefaultReportDescriptor;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; DebugPrint((&amp;quot;Using Hard-coded Report descriptor\n&amp;quot;));&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;... 중략 ...&lt;/p&gt; &lt;p&gt;case IRP_MN_REMOVE_DEVICE:&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // free memory if allocated for report descriptor&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; //&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 이 부분도 주석처리해야 한다. 왜냐면 레지스트리에서부터 읽어들이지 않았기 때문에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 메모리 할당이 안되어 있기 때문이다. 그냥 두어도 상관없을거 같지만 메모리 해제부분이니&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; // 꺼림칙하므로 되도록이면 제거하길 바란다.&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; if(deviceInfo-&amp;gt;ReadReportDescFromRegistry)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ExFreePool(deviceInfo-&amp;gt;ReportDescriptor);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; SET_NEW_PNP_STATE(deviceInfo, Deleted);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; ntStatus = STATUS_SUCCESS; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; break; &amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;이제 vhidmini 샘플을 컴파일하고 VMware 에 vhidmini.sys 와 vhidmini.inf 파일을 복사하자. 그리고 devcon 명령으로 앞서했던 것처럼 install 을 해보자. 설치를 하고나면 장치관리자의 기존에 있던 &amp;quot;HID 준수장치&amp;quot; 라는 것은 없어지고 마우스항목에 &amp;quot;HID 규격 마우스&amp;quot; 가 추가되는 것을 볼 수 있을 것이다.(ㅎㅎ 이맛을 보려고.. 밤을새고 삽질을..) 이제.. 장치관리자에서 새로 추가된 &amp;quot;HID 규격 마우스&amp;quot; 를 선택한 뒤에 속성을 보자. 속성을 선택한 뒤 &amp;quot;자세히&amp;quot; 라는 것을 클릭한다. 그리고 장치인스턴스 ID 라는 것을 보라. HID\MyVirtualHidDevice&amp;amp;Col01 라고 되어있는 것을 볼 수 있다. 또한, 일치하는 장치 ID 를 선택하면 hid_device_system_mouse 라고 되어있다. 즉, 마우스로 인식이 되었다는 것이다. 가상 HID 디바이스 위에서 마우스 장치가 인식되어 있는 것이다. 이제 가상 HID 디바이스와 어플리케이션 간에 통신루틴을 프로그래밍하고 어플리케이션의 명령에따라 상위 클래스로 IRP/URB 같은 요청을 (이거참.. 이 레이어에서는 어떤 요청을 사용해야하는 건지 또 공부해야하는군.. -_-; USB 강의 문서에 보면 상위 클래스는 URB 통신을 한다고 나와있었다..) 날려주면 키보드나 마우스 같은 장치들을 에뮬레이션 시킬수 있다. 곧, 가상장치를 조종할 수 있다. 하지만? 그리 쉽지는 않을 것이다. vhidmini 샘플에는 testvhid 라는 어플리케이션 소스도 같이 들어있는데 이 testvhid 소스는 어플리케이션단에서 vhid miniport 드라이버와 통신하는 예제이다. 참고로 아무런 수정없이 샘플만 컴파일해도 어플리케이션과 드라이버 사이에 제대로 통신이 이루어지지않는다. 역시나 이 문제는 HID Report Descriptor 의 데이타의 구성문제에 속한다. 한번 고생한 것이 또다시 반복되는 시점이기도 하다. 이 부분을 해결하면 어플리케이션은 2 또는 3 가지의 top-level collection 중에서 사용자정의(User-Defined) 콜렉션을 통해서 miniport 드라이버와 통신을 할 수 있게되고 이 통신에 따라서 마우스 IRP 를 상위 클래스로 때려주면 된다. 더 자세한 내용은 스스로 연구하길 바란다. 이상으로 이번문서를 마무리하려고 한다. 왜냐면 이제 테스트 기반이 마련되었으니 나머지 추가구현은 스스로가 해야할 몫이기 때문이다. 어떠한 목적으로 개발하던간에 그 이상은 이제 필자가 관여할 부분이 아닌것 같다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;어차피 이 문서의 목적은 가상 마우스를 제작하는 것을 중점으로 삶는 것보다도 모르는 분야를 독학하며 개척해 나갈때 자신의 공부스타일의 한 예로써 제시하는 것이었다. 여기서 거론된 공부스타일을 종합해 본다면 이렇게 말할 수 있을것 같다. &amp;quot;관례를 찾아냄으로써 DIFF 를 추출해내는 공부법&amp;quot; 이라고 할 수 있다. 즉, 최대한 많은 자료들을 검색으로 긁어모은 뒤에 분리분석 작업을 통하여 동일한 부분의 반복을 찾아낸다. 찾아낸 반복내용이 있다면 결국 그 반복은 해당 프로그래밍의 관례에 속한다. 즉, 해당 관례는 몸으로 빨아들이고 차이가 나는 지점에서 기술을 흡수한다. 이런식의 반복학습을 통하여 더이상 다른 코드나 정보들을 찾아낼 수 없다고 판단이 들때 그 기술은 자기것이 된다. 필자는 유저레벨을 공부할때 항상 이방식을 택해왔다. 정보가 고갈되고 더이상 찾아낼수 없을때까지 긴시간을 할애해서 리서치를 먼저 한다. 그 뒤에 코딩으로 들어간다. 그리고 관례코드를 따른다. 그렇게되면 생전 처음보는 프로그래밍에서도 어느지점은 건드려도 되고 어느지점은 절대 건드려서는 안되는지 쉽게(? 정확히가 맞겠다) 익힐수 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;이제는 커널레벨 공부를시작하면서 이 고통스럽고도 지루한 공부방식을 다시 사용하고자하며 다른 사람에게 조그마한 도움이 되고자 이런 문서를 작성하였다. (같이 게임에 미쳐서 광랩하던 친구가 갑자기 URL 을 려줘서 읽어 보았더니 국가에서 인증한 기술이라는 자랑스런 인증서와 함께 뭔가를 팔고있었다. 보란듯이 대놓고 말이다. 디자인도 쌈빡해서 사고싶게 만드는 그것.. 그게 뭔지는 대충 말안해도 알겠지만.. 이 문서를 빨리 공개해야하겠다는 생각이 들었다. 원래는 문서를 다 작성해놓고도 공개하지않는 방향으로 생각을 굳혔다가 아무래도 생각이 바뀌기 시작하였다. 그 이유는 뒷부분의 부록을 보라..) 아마 이 방식으로 공부하는 사람들이 많겠지만 그렇지 않을수도 있을 것이다. 적어도 이렇게 공부할땐 뼈를 깎듯이 힘들지만 원하고자 하는 지식을 얻으면 그 지식의 깊이가 뼈속으로 스며들 것이다. 필자처럼 어떤 새로운 분야에 공부를 시작하거나 공부하는 방법을 몰라서 물어보려는 사람들이 있다면 이 문서를 읽어보라고 말하고 싶다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;잡설&amp;gt;&lt;/p&gt; &lt;p&gt;필자가 만약에 커널디버깅을 잘 다뤘다면 아마도 쉽게 문제를 해결했을지도 모르겠다. 하지만 필자는 귀차니즘 때문에 커널디버깅을 좋아하지 않았고 결국, 공부도하지 않았다. (요즘들어 먹고 살라니.. 공부중이다.. -_-;) 그런데 필자는 오히려 디버거를 쓰지 않으면 않을수록 프로그램에 대한 이해도는 높아진다고 생각한다. 왜냐면 사람의 머리는 충분히 상황을 시뮬레이션 할 수 있다고 생각하기 때문이다. 에뮬레이션은 불가능하겠지만 시뮬레이션은 가능하다. 그리고 이 작업을 통해서 문제가 발생되는 지점을 캣치할 수 있다고 생각한다. 그렇게 되었을때 남보다 더 느릴지 몰라도 이해도는 훨씬더 깊이있는 굴곡을 생성해낸다고 생각한다. 어쩌면 그렇게 믿고싶은 것일지도 모르겠다. 적어도 자신은 그렇게 소신을 갖고있다. 그렇다고 커널디버깅을 배우는 것을 말리거나 도외시하라는 것은 절대 아니다. 필수적으로 갖고가야할 기술이라는 점에는 변함이 없지만 두가지를 모두 안배하는 것이 스스로에게 좀 더 풍요로운 지식을 가져다 줄 것이라는 점을 인지했으면 좋겠다는 의미이다. &amp;quot;Art of Hooking&amp;quot; 이라는 문서처럼 스스로의 깨달음을 전달하려고 쓴 문서는 아니지만 이 시간에도 같은 문제로 삽질하고있을 그들에게(아직도 정확한 답변을 보지 못한 질문자들이 인터넷에 깔려있음을.. 이미 보여줬다..) 이틀이라는 시간을 좀 더 귀중한 곳에 쓸 수 있도록 해줄 수 있다는 것은 행복한 일이라고 생각한다. 만약 누군가에게 이런 도움을 지속적으로 받을수 있었다면 본인은 솔로여야할 이유가 없었을 것이리라.. (아쉽게도 영어를 못하니 국내만이라도 도움을 받으면 좋을듯 싶다.) 참고로.. 이 문서는 주제를 인지하는 시점부터 해결과정을 도출해내는 모든 전 과정이 거의 실시간으로 쓰여졌다.. 그렇게 해야만이 이 문서의 목적인 &amp;quot;가상마우스&amp;quot; 와 &amp;quot;공부방법론&amp;quot; 두가지를 모두 전달할 수 있다고 판단했기 때문이다. 필자는 누군가 이 문서를 읽고 얻은게 있었다면 그것만으로 행복할 것이다. 하드에 처박혀 쓰레기가 된채 어느날 자신도 모르게 삭제되는 그런 정보가 아니라는 점만으로도 충분히 가치있는 것이니까..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록1: 필자가 생각하는 에뮬레이션과 시뮬레이션의 차이점]&lt;/p&gt; &lt;p&gt;에뮬레이션: 기계의 톱니바뀌처럼 구성요소들의 기능자체들이 모두 동일하게 작동해야 한다. (기능/작동의 동일화)&lt;/p&gt; &lt;p&gt;시뮬레이션: 기능자체를 동일하게 할 필요없이 입/출력되는 수치/값만 동일하면 된다. (수치/데이타의 동일화)&lt;/p&gt; &lt;p&gt;(필자주: 틀렸을 수도 있다. 정확하지않다. 다만, 여태까지 몸으로 와닿는 느낌자체를 말로 풀어써본 것 뿐이다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[부록2: 시중에 떠도는 물리형 Auto Mouse 탐지법]&lt;/p&gt; &lt;p&gt;먼저, 가상장치에 대한 것부터 언급해보고 물리형으로 넘어가겠다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;1. 가상장치 탐지방법&amp;gt;&lt;/p&gt; &lt;p&gt;재밌는 사실이 있는데 아는 사람은 알 것이고 모르는 사람은 모를 것이다.&lt;/p&gt; &lt;p&gt;MSPRESS 에 보면 짜가장치(FakeDevice) 탐색법이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&quot; target=&quot;_blank&quot;&gt;http://www.microsoft.com/mspress/books/sampchap/6262.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;-------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;HANDLE CtestDlg::FindFakeDevice()&lt;/p&gt; &lt;p&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; GUID hidguid;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; HidD_GetHidGuid(&amp;amp;hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; CDeviceList devlist(hidguid);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; int ndevices = devlist.Initialize();&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; for(int i = 0; i &amp;lt; ndevices; ++i)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HANDLE h = CreateFile(devlist.m_list[i].m_linkname, 0,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FILE_SHARE_READ | FILE_SHARE_WRITE,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(h == INVALID_HANDLE_VALUE)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HIDD_ATTRIBUTES attr = {sizeof(HIDD_ATTRIBUTES)};&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;BOOLEAN okay = HidD_GetAttributes(h, &amp;amp;attr);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CloseHandle(h);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(!okay)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if(attr.VendorID != HIDFAKE_VID ||&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; attr.ProductID != HIDFAKE_PID)&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return CreateFile(devlist.m_list[i].m_linkname,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GENERIC_READ | GENERIC_WRITE, 0, NULL,&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OPEN_EXISTING, 0, NULL);&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; return INVALID_HANDLE_VALUE;&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;위의 짜가장치 탐색법은 골때리게 단순하다. 결국에는 HIDFAKE_VID 와 HIDFAKE_PID 를 체크하는 개념이다. 즉, 제작사(Vendor ID)와 제품번호(Product ID)를 가지고 짜가인지 판별하겠다는 개념이다. 그렇다면 제작사와 제품번호는 속일수 없다고 생각하는가? 커널을 뒤짚어 엎는(Subvert) 판국에 저렇게 단순하게 비교해서는 가상장치를 막을수 없다. 위의코드를 보고 판단을 하길 가상장치는 다 막겠다고 판단한다면 정말 큰일이다. 어처구니 없는 싸움이 키보드보안이래 또 발생할 것이기 때문이다. 위의 코드가 의미하는 바를 잘못해석하면 안된다. 위의 코드는 이렇게 해석해야 한다. 그 어떠한 가상장치를 막을수 있다는 컨셉하에 위의 코드를 만들길 시도한것이 아니라 고정장치를 알아내기위해 만들어진 컨셉이라는 점을 말이다. 단지 정형화 되어있는 즉, 고정되어있는 상태에서는 가능할 수 있겠다. 이해를 돕기위해 예를한가지 들어보자. VMware 같은 가상머신 안에서 작동하는 것인지 정도는 파악할 수 있지 않을까 싶다. 왜냐면 VMware 가 동적으로 제작사와 제품번호를 바꿔야할 까닭이 없지않은가? 다르게 말하면 VMware 가 굳이 자기 제품정보를 굳이 속이거나 변덕스럽게 수시로 바꿔야할 필요가 전혀 없다는 얘기다. 이런경우에는 마치 하드웨어처럼 고정장치로 봐도 무방하다. 고로 VMware 에는 항상 고정된 장치가 있다고 판단해도 될 것이며 VMware 안에 구현된 장치들 중에는 가상장치들이 있으므로 항상 디텍트 할 수 있단 얘기가 되므로 위의 짜가장치 탐색법은 그러한 경우에 사용할 수 있는 컨셉이라는 소리다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;아직 더 깊이 연구해보지는 않았지만 가상장치와 전쟁을 선포할 경우에 또 하나의 &amp;quot;키보드보안&amp;quot; 같은 파국으로 치닫기에 좋은 스토리가 탄생할 것이다. 차라리 이것을 좀 더 유용한 곳에 사용해보면 어떨까? 바로!! 물리형 Auto Mouse 를 탐지하는 것이다. 기술은 적합한 곳에 쓰라고 있는 것이지 말도안되는 헛다리 싸움에 쓰라고 존재하지 않는다. 기술을 적용시킬때는 단순히 눈과 머리로만 판단하지말고 포괄적인 정황을 바탕으로 자신의 가슴속에 확신이 설때 비로소 본격적인 전쟁에 들어가야 한다. 그저 돈이된다고 키보드보안처럼 너도나도 발담궈놓고 아무도 책임지지않고 아무도 발도 못빼는 승자없는 싸움에 휘말리기 싫다면 필히 이 말을 웃어넘기지 말아야 할 것이다.(아마, 이젠 더이상 발을 빼지도 못할것이다.. 담구지 말라고 뜯어말려도&lt;/p&gt; &lt;p&gt;담궜으니 해야할 일은 그저 땜빵밖에 뭐가 더 있겠는가.. ㅉㅉ)&lt;/p&gt; &lt;p&gt;-----------------------------------------------------------------------------------------&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;2. 물리형 Auto Mouse 탐지&amp;gt;&lt;/p&gt; &lt;p&gt;물리형 Auto Mouse 를 탐지하는 것의 기본바탕은 앞서 짜가장치 탐색에 사용된 코드를 그대로 채용하면 되겠다. 단, 제작사와 제품번호만이 아닌 추가정보를 이용할 필요가 있겠다. 그런데, 왜 효용성이 물리형 Auto Mouse 를 탐지하는 것에 효력이 있을까? 그 이유는 간단하다. 다음과 같은 정보를 보자. 필자는 최근에 오픈된 MMORPG 온라인 게임의 Auto Mouse 를 구매해보았다. 과연 어떻게 돌아가는지 궁금증도 있었고 진짜 완벽하게 구동이 되는것인지 두눈으로 확인해보고 싶었기 때문이었다. 그런데 일단, 한군데의 제품은 구동이 제대로 안되는 것을 확인하였다. 다만, 마우스 입력이나 키보드 입력은 그대로 게임속으로 전달되고 있다는 점에 주목하였다. 과연 그러한 것을 어떻게 탐지해낼 수 있을까? 다음은 USB View 라는 프로그램으로 Auto Mouse 장치의 Descriptor 를 본 화면이다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;lt;Auto Mouse HID Descriptor&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;quot;USB Composite 장치&amp;quot;&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;Device Descriptor:&lt;/p&gt; &lt;p&gt;bcdUSB: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x0200&lt;/p&gt; &lt;p&gt;bDeviceClass: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00&lt;/p&gt; &lt;p&gt;bDeviceSubClass: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bDeviceProtocol: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x00&lt;/p&gt; &lt;p&gt;bMaxPacketSize0: &amp;nbsp; &amp;nbsp; &amp;nbsp;0x20 (32)&lt;/p&gt; &lt;p&gt;idVendor: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x03EB (Atmel Corporation)&lt;/p&gt; &lt;p&gt;idProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x4743&lt;/p&gt; &lt;p&gt;bcdDevice: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x1000&lt;/p&gt; &lt;p&gt;iManufacturer: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x01&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY&amp;quot;&lt;/p&gt; &lt;p&gt;iProduct: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x02&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;ATPLAY PRO8&amp;quot;&lt;/p&gt; &lt;p&gt;iSerialNumber: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x03&lt;/p&gt; &lt;p&gt;0x0409: &amp;quot;1.0.0&amp;quot;&lt;/p&gt; &lt;p&gt;bNumConfigurations: &amp;nbsp; 0x01&lt;/p&gt; &lt;p&gt;... 생략 ...&lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;그렇다. idVendor 가 제작사이고 idProduct 가 제품번호이겠다. 이 정보는 필자가 예상컨대 고정이라 할 수 있다. 일단, 텍스트를 주의깊게 보자. &amp;quot;Atmel Corporation&amp;quot; 이 보이는가? 해커들이 가장 많이 사용한다는 그 유명한 &amp;quot;Atmel&amp;quot; 칩이 사용되었다. 일명 FPGA 칩이라고 불리운다. 이 FPGA 칩은 프로그래밍 가능한 이점이 있다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;(사견: 언제부터 마우스가 Atmel 칩으로 제작되었던가? 그래서 오토마우스가 그리도&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;비싼거였나보다.. 싸구려 PIC 칩만으로도 마우스를 만들수 있다. 전자업계는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;원래 원가전쟁을 벌이는 계통이라서 단 1원이라도 원가를 절감해 보려고&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;깎고깎고 전쟁을 벌인다. 필자의 친구가 전자회사 CEO 라서 이점은 매우 잘&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;알고있다. 그 친구의 말을 빌어보자면 진짜 1원갖고 쪼잔하게 굴 수 밖에&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;없다고 한다. 살아남아야 하니까 말이다.. 그런데 FPGA 칩을 쓰는 것을 보면&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;좀 수상하다. 왜 재프로그래밍이 가능한 칩을 쓰는 것인가.. 재수없으면 기타장치&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;메모리스틱 리더기같은 것들이 연결되어 있을수도 있으므로 함부로 판단하기는&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이르지만 아마도 대량유통되는 칩이 아닌 DIY(사제품)칩을 쓴다는 것은 기정&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;사실이라고 추측할만 하지않은가? 필자가 대에충 찾아보니 Auto Mouse 제작사&lt;/p&gt; &lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;두군데가 Atmel 칩을 사용하고 있었다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;만약 이 Atmel 칩이 필자가 아는 것과 달리 재프로그래밍이 가능한 기능이 없다면 게임업계에서는 대박의 찬스를 잡은 것이리라.. 왜? 고정이잖은가? 고정!! 또, 재미난 정보를 볼 수 있는데 바로 그 유명하다고 하는 &amp;quot;ATPLAY&amp;quot; 라는 마크가 찍혀있다. 아주 그냥 상호를 갖다가 박아놓은거보니 장사할 생가이 없다하겠다.&lt;/p&gt; &lt;p&gt;일단, 칩이 Atmel 칩으로 제작되어있는 USB 형 물리장치들을 사용하는 사용자는 모두 감시대상순위로 집어넣어도 십중팔구는 맞아떨어질 것이다. 특히나 Atmel 칩에 상관없이 상호명 ATPLAY 가 박혀있다면 그 사용자는 거의 Auto Mouse 를 사용하고 있을 확률이 99.9% 라고 할 수 있겠다. 그리고 USB View 같은 프로그램이 사용하는 루틴들은 위에서 언급된 루틴들에서 크게 벗어나지는 않을테니 쉽게탐지할 수 있다고 감히 추측해본다. 딱한가지 우려되는 사항이 있다면 프로그래밍 가능한 칩이기 때문에 업데이트 기능으로&lt;/p&gt; &lt;p&gt;펌웨어를 갈아치울 경우에 난감하게 될 것이다. 하지만 방금 언급한 방식을 사용한다면 Auto Mouse 제작사의 미래고객이 아닌 현재 고객들은 99.9% 가 탐지된다고 봐도 무방할 것이다. 물론, Auto Mouse 의 종류별로 이짓을 해야겠지만.. 프로그래머들의 습성상 모두 식별자를 기록해놓았을테니(아마, Atmel 칩에 코딩을 의뢰하거나 혹은 Atmel 칩에 프로그램이 가능한 사람을 영입했겠지만 프로그래머들이 그런거 생각안한다. 왜냐면 원리원칙을 따르려는 프로그래머의 심리상 바보같이 위에처럼 ATPLAY 를 박는게 미덕으로&lt;/p&gt; &lt;p&gt;생각할 것이기 때문이다.) 행동만 빨리 취한다면 현재 Auto Mouse 사용자들의 태반은 모두 다 탐지해낼 수 있을 것이라고 감히 판단해본다. 즉, 물리형은 고정이라는 변수를 잘 활용할 수 있기에 탐지도 비교적 수월한 편에 속한다는 것이다. 한가지 더 재미난 상상을 해보자.. 과연 Auto Mouse 업체에서 펌웨어 업데이트 기능을 추가로 만들어내는데 얼마나 시간이 걸릴까? 누가 더 대응이 빠를까..? 과연 이 전쟁에서 Auto Mouse 업체의 대응이 빠를까? 아니면 막는자의 대응이 더 빠를까? 아마도 덩치가 작은쪽이 더 빠르겠지만 두고볼 일일 것이다. 이 전쟁은 어느한쪽의 시간전쟁일 뿐이다.. 정확하고 빠른판단이 내려지면 그대로 바로 행하는 쪽이 이기는 것이다. 현재로써 본 필자의 생각으로는 물리형 Auto Mouse 는 막을 수 있다. 이 문서가 나온 시점 앞으로가 문제이다.. 점차 Auto Mouse 는 가상마우스로 진화를 꿈꾸고 있기 때문이다. 그것이 바로 기술의 대세인 것이다. 오늘의 기술이 내일의 쓰레기가 되어버리는 시대에서 속도전의 중요함이다. 승자는 과연 누가 될까? 아무도 모른다.. 기술은 끝이 없으니까.. 마이 골치아픈 것이다.. -_-; 어디까지나.. 필자 개인이 현 상태를 진단해본 사견일 뿐이다. 이 이상 어케 더 판단하랴..&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[HID Descriptor Tool]&lt;/p&gt; &lt;p&gt;USB.ORG 공식 사이트에서 받을수 있음&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&quot; target=&quot;_blank&quot;&gt;http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(위에서 언급한 사이트 이외 참고한 사이트)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/485&quot; target=&quot;_blank&quot;&gt;http://kkamagui.tistory.com/485&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.keil.com/forum/docs/thread13037.asp&quot; target=&quot;_blank&quot;&gt;http://www.keil.com/forum/docs/thread13037.asp&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.keil.com/forum/docs/thread13037.asp&quot; target=&quot;_blank&quot;&gt;Secret is...&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;출처 :&amp;nbsp;&lt;a href=&quot;http://www.secret.pe.kr/Language/19096&quot;&gt;http://www.secret.pe.kr/Language/19096&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/441204</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/441204#comment</comments>			<pubDate>Sun, 14 Feb 2016 09:43:02 +0900</pubDate>
		</item><item>
			<title>가상 HID 제작경험글(?)</title>
			<link>https://autolabs.co.kr/board_cFDS08/441049</link>
				<description>&lt;p&gt;언젠가는 이런 시행착오들이 도움이 될수도 있겠죠?ㅎ&lt;/p&gt; &lt;p&gt;저도 언젠가 이정도 수준에 다다르면 느끼게 될것 같아 기록해봅니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/472&quot;&gt;2008.05.20&amp;nbsp;&amp;nbsp; &amp;nbsp;대략적인 테스트를 완료했습니다. ^^;;;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/476&quot;&gt;2008.05.24&amp;nbsp;&amp;nbsp; &amp;nbsp;키보드 스캔 코드(Scan Code) 표&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/475&quot;&gt;2008.05.24&amp;nbsp;&amp;nbsp; &amp;nbsp;키보드 및 마우스 필터드라이버를 동적으로 로딩할 수 있도록 작업 중입니다.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/478&quot;&gt;2008.05.26&amp;nbsp;&amp;nbsp; &amp;nbsp;주말 내내 필터 드라이버 동적 로딩이랑 가상l HID(Virtual HID) 드라이버 작업을 했습니다. ㅜ_ㅜ&amp;nbsp;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/480&quot;&gt;2008.06.01&amp;nbsp;&amp;nbsp; &amp;nbsp;무시무시한 보안 프로그램들... 필터 드라이버를 완전 망쳐놨습니다. ㅜ_ㅜ&amp;nbsp;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/482&quot;&gt;2008.06.03&amp;nbsp;&amp;nbsp; &amp;nbsp;가상 HID(Virtual HID) 작업중입니다. @0@&amp;nbsp;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/483&quot;&gt;2008.06.04&amp;nbsp;&amp;nbsp; &amp;nbsp;가상 HID(Virtual HID)관련 작업이 예상보다 많이 늦어지고 있습니다. ㅜ_ㅜ&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/485&quot;&gt;2008.06.08&amp;nbsp;&amp;nbsp; &amp;nbsp;드디어 가상 HID 드라이버(Virtual HID Driver)가 동작했습니다. ㅜ_ㅜ)/~!!!&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/489&quot;&gt;2008.06.15&amp;nbsp;&amp;nbsp; &amp;nbsp;Kernel Exploit 관련 자료들&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/529&quot;&gt;2008.08.29&amp;nbsp;&amp;nbsp; &amp;nbsp;아아~ 간만에 또 키보드 마우스 필터 드라이버 소스를 손봤습니다. ^^;;;;&amp;nbsp;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/531&quot;&gt;2008.08.30&amp;nbsp;&amp;nbsp; &amp;nbsp;숨어있는 드라이버를 찾아내는 방법&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://kkamagui.tistory.com/567&quot;&gt;2008.10.14&amp;nbsp;&amp;nbsp; &amp;nbsp;멀티코어를 지원하는 OS보다 멀티코어를 지원하는 드라이버가 더 어렵군요. ㅠㅠ&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/441049</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/441049#comment</comments>			<pubDate>Sat, 13 Feb 2016 22:31:33 +0900</pubDate>
		</item><item>
			<title>Device Driver 제작</title>
			<link>https://autolabs.co.kr/board_cFDS08/441024</link>
				<description>&lt;p&gt;드라이버 제작과는 관계가 있는것 같아 링크걸어봅니다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 1. Visual Studio 2010 - Device Driver 제작- Hello World 예제&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=919&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=919&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 2. Device Driver 응용 프로그램의 빌드 스크립트&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=921&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=921&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 3. NT Legacy 드라이버를 이용하여 C#에서 Port 입출력&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=932&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=932&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 4. Device Driver 응용 프로그램의 빌드 스크립트 - 두번째 이야기&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=936&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=936&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 5. NT Legacy 드라이버: 프로세스(EXE) 생성/제거 모니터링&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=937&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=937&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 6. ZwTerminateProcess로 프로세스를 종료하는 Device Driver 프로그램&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=2904&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=2904&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;DDK: 7. 정식 인증서가 있는 경우 Device Driver 서명하는 방법&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=2914&quot;&gt;http://www.sysnet.pe.kr/Default.aspx?mode=2&amp;amp;sub=0&amp;amp;pageno=0&amp;amp;detail=1&amp;amp;wid=2914&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/441024</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/441024#comment</comments>			<pubDate>Sat, 13 Feb 2016 22:20:45 +0900</pubDate>
		</item><item>
			<title>Virtual HID 개념 슬라이더 강좌자료</title>
			<link>https://autolabs.co.kr/board_cFDS08/441017</link>
				<description>&lt;p&gt;&lt;a href=&quot;http://prezi.com/vgb0tkqrpvap/?utm_campaign=share&amp;amp;utm_medium=copy&amp;amp;rc=ex0share&quot;&gt;http://prezi.com/vgb0tkqrpvap/?utm_campaign=share&amp;amp;utm_medium=copy&amp;amp;rc=ex0share&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;좋은자료가 있어 퍼옵니다 ㅎ&lt;/p&gt; &lt;p&gt;기본 개념을 학습하는데에는 좋은자료 같아 올려봅니다.&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/441017</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/441017#comment</comments>			<pubDate>Sat, 13 Feb 2016 22:10:59 +0900</pubDate>
		</item><item>
			<title>아두이노HID+오토핫키 조합...</title>
			<link>https://autolabs.co.kr/board_cFDS08/409090</link>
				<description>&lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;아두이노HID+오토핫키 조합을 사용하면...&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;코딩을 조금 하실줄 아는분들은....어쩌면...지존오토보다 더 저렴한 가격에&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;만능자동화도구를 얻으실수 있으실듯하네요....&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;물론 프로그램 최적화 정도에 따라 다르겠지만..말이죠...&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;이거 컨텐츠 샵에서 강좌 판매 한번 해볼까용?ㅎㅎ&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>	<category>아두이노HID+오토핫키</category><category>조합...</category>			<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/409090</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/409090#comment</comments>			<pubDate>Thu, 19 Nov 2015 10:29:28 +0900</pubDate>
		</item><item>
			<title>지존오토 hid드라이브 삭제 후 재설치</title>
			<link>https://autolabs.co.kr/board_cFDS08/406868</link>
				<description>&lt;div style=&quot;text-align: center;&quot;&gt;믹스님 보십시요 ㅎ&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://autolabs.co.kr/files/attach/images/4835/868/406/bb4fd705c3bc91177a8c9cde1492adaa.PNG&quot; alt=&quot;캡처.PNG&quot; width=&quot;760&quot; height=&quot;552&quot; style=&quot;line-height: 1.5;&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;지존오토가 사용하는 드라이버가 USB Composite Device입니다.&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;오른쪽 클릭해서 제거후에 다시 잡아서 해보십시요 ㅎ&lt;/div&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>	<category>지존오토</category><category>hid드라이브</category><category>삭제</category><category>후</category><category>재설치</category>			<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/406868</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/406868#comment</comments>			<pubDate>Sat, 07 Nov 2015 17:05:34 +0900</pubDate>
		</item><item>
			<title>vhid driver Source(Virtual HID 드라이버 소스)</title>
			<link>https://autolabs.co.kr/board_cFDS08/369987</link>
				<description>&lt;p&gt;키보드 / 마우스 / 조이스틱 / 멀티터치 등을 지원하는 가상 HID 드라이버용 소스 입니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;공개된것 이긴한대 구형이고 해서 최신버전에 맞도록 고쳐야 사용이 가능합니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;수정 작업은 저도 시간이 나는대로 차근차근 진행 하려구요..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;아무튼 이렇게 올려 놓습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;같이 해봐용~&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>포스몬</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/369987</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/369987#comment</comments>			<pubDate>Tue, 22 Sep 2015 18:56:18 +0900</pubDate>
		</item><item>
			<title>오토핫키와 VHID</title>
			<link>https://autolabs.co.kr/board_cFDS08/369982</link>
				<description>&lt;p&gt;오늘 &amp;nbsp;새로운 힌트를 찾아 기록합니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;포스몬님이 말씀해주신, 오토핫키의 DllCall 함수 이용과 C언어로 만들어진 VHID DLL모듈...&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;궁극적인 목표는 VHID DLL을 만들수 있어야...&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/369982</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/369982#comment</comments>			<pubDate>Tue, 22 Sep 2015 18:43:52 +0900</pubDate>
		</item><item>
			<title>셀레니움 개발환경 셋팅 및 간단한 테스트!</title>
			<link>https://autolabs.co.kr/board_cFDS08/358833</link>
				<description>&lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;1. 자바 설치(진행완료)&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;2. 이클립스 설치(진행완료)&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;3. 셀레니움 라이브러리 다운로드(진행완료)&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;4. 셀레니움IDE 설치(건너뜀..추후 진행)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;5. 자바 프로젝트 생성&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;(진행완료)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;- junit/셀레니움 서버/셀레니움 클라이언트 jre추가&lt;/p&gt; &lt;p&gt;&amp;nbsp;- firefox 브라우저에서 구글, 네이버, 네이트 5초간격으로 띄우는 소스코드&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;6. 테스트&lt;/span&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;진행완료&lt;/span&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;img src=&quot;https://autolabs.co.kr/files/attach/images/356962/833/358/095f783cd5f963d9f89d45e79415984f.PNG&quot; alt=&quot;캡처.PNG&quot; width=&quot;1948&quot; height=&quot;1029&quot; /&gt; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;* 오 되긴하네요...그런데 이런 일련의 동작을 할려면 RC서버가 작동되어야만 하네요..&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&amp;nbsp; 오토핫키 처럼 간단하게 exe파일만 call해서 이런 동작을 할수 있다면..좋을텐데 말이죠..ㅎ&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&amp;nbsp; 일단 오늘은 여기까지만!&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;* 제가 참고한 사이트들 올려봅니다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&amp;nbsp; 특히 이중에서 동영상이 정말 많은 도움이 됬네요..ㅎ&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;* 참고 사이트&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 17.7273px;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=zylSll8hsPs&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=zylSll8hsPs&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;a href=&quot;http://myinbox.tistory.com/14&quot; target=&quot;_blank&quot;&gt;http://myinbox.tistory.com/14&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;a href=&quot;http://soonrok.tistory.com/177&quot; target=&quot;_blank&quot; style=&quot;line-height: 1.5;&quot;&gt;http://soonrok.tistory.com/177&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/358833</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/358833#comment</comments>			<pubDate>Tue, 08 Sep 2015 01:29:45 +0900</pubDate>
		</item><item>
			<title>셀레니움에 대한 간략한 이해!?</title>
			<link>https://autolabs.co.kr/board_cFDS08/357864</link>
				<description>&lt;p&gt;포스몬님이 올려주신 셀레니움 공식 사이트를 조끔 읽어보았습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그냥 제가 대충 이해한 바는 이렇습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;*&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;셀레니움은 웹 자동화에 대한 도구이다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&amp;nbsp;- 사이트의 소개해준 한 예제에서는 구글에 검색어를 자동으로 입력해서 결과를 받아와 화면에 print해 준다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;* 셀레니움은 크로스 브라우징을 지원한다&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 익스, 크롬, 파폭, 사파리, 오페라, IOS, Android 등...브라우저 환경에 관계없이 라이브러리가 호환 및 지원된다.&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 여기서 IOS와 Android가 왜 들어있는지..참 흥미롭네요??&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;* 셀레니움이란 하나의 라이브러리이다(Server, Client 개념이 있으나, 일단은 Client 개념으로만 접근했습니다.)&lt;/p&gt; &lt;p&gt;&amp;nbsp;- 라이브러리를 제공함으로써 관련 API에 대한 문서를 제공한다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;*&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;셀레니움을 사용하기 위해서는 아래의 언어 중 하나를 사용할 줄 알아야 한다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&amp;nbsp;- JAVA, C#, Python, Ruby, Perl, PHP&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;간단하게 따라해본다면 사이트예제인 구글검색 키워드를 입력해서 결과를 받아오는걸 따라 해보는게 가장 쉬워보이긴 합니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그러려면 셀레니움 라이브러리를 활용할수 있는 환경이 구축되어야겠죠?&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;이제 이걸 어떻게 활용 하느냐~가 문제겠네요 ㅎ&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;뭐 돈되는거 없나요? ㅎㅎㅎㅎㅎ&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/357864</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/357864#comment</comments>			<pubDate>Wed, 02 Sep 2015 09:03:16 +0900</pubDate>
		</item><item>
			<title>셀레니움 이란? 웹드라이버란?</title>
			<link>https://autolabs.co.kr/board_cFDS08/357690</link>
				<description>&lt;p style=&quot;font-size:13px;&quot;&gt;우선 한줄정리 : 웹 자동화&lt;/p&gt; &lt;p style=&quot;font-size:13px;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;http://www.seleniumhq.org/ &amp;lt;-- 이곳에서 프로그래밍에 필요한 소스및 모듈 들을 제공하고있습니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;웹 자동화가 필요한 곳은? &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;1. &lt;/span&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;웹사이트 테스트.. (반복적인 테스트로 사이트의 내구성과 오류를 검증하는 부분등에 많이 이용되죠)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;2. 자동로그인 및 자동화.. 무슨말이냐.?&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt; (로그인/웹게임 등등을 자동화 한는대 사용이 가능하죠..)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;3. 다음/네이버/카카오 등등 의 웹 관련 광고 목적으로도 광범위하게 이용할수있죠...&lt;/p&gt; &lt;p&gt; (예를들어 자동덧글 이라던가.. 랭킹위치 정보수집 등등..... )&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height:1.5;&quot;&gt;주 목적은 익스/크롬/파폭 등의 브라우저 들을 사람손 안대고 자동으로 제어 한다는겁니다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;혹시라도 관심 있으신분은 함께 배워가요~ ^.^&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-size:13px;line-height:19.5px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>포스몬</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/357690</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/357690#comment</comments>			<pubDate>Tue, 01 Sep 2015 02:06:57 +0900</pubDate>
		</item><item>
			<title>시리얼 통신 공부중</title>
			<link>https://autolabs.co.kr/board_cFDS08/348609</link>
				<description>&lt;p&gt;아두이노를 받고, ahk로 간단하게 테스트 해본후,&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;MFC를 이용해서 아두이노와 시리얼통신을 공부중입니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;인터넷에 있는 예제들은 대부분 CString으로 주고받고 하더라구요..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그래서 저는 BYTE로 안정성있게 통신하는 방식으로 개발중입니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;일단은 RS232라는걸 공부해서 해보고 있는데. 재밌네요!&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/348609</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/348609#comment</comments>			<pubDate>Wed, 29 Apr 2015 12:40:43 +0900</pubDate>
		</item><item>
			<title>뒤늦은 후기 2탄 입니다.</title>
			<link>https://autolabs.co.kr/board_cFDS08/348149</link>
				<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;지금 살고있는 집 전세가 만기가 다가와서 &lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;집주인에게 전화를 걸었는데....&lt;/p&gt; &lt;p&gt;집 주인 아들래미가 이 집에 들어온다고 나가라고 하네요 ㅠㅠ&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그 후로 폭풍 부동산 검색에 현장 매물 확인하고 바뿌게 지내고 있습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;dll 함수는 성공적으로 호출을 성공했는데 마우스 이동 하는 부분에서 프로그램이 뻗어버리네요..&lt;/p&gt; &lt;p&gt;아무래도 판매자분하고 얘기를 좀 해봐야 될거같아요.&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>피부탄</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/348149</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/348149#comment</comments>			<pubDate>Tue, 21 Apr 2015 15:56:15 +0900</pubDate>
		</item><item>
			<title>usb후기 및 호출 방법 조언 부탁드립니다.</title>
			<link>https://autolabs.co.kr/board_cFDS08/347909</link>
				<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;VB 6.0에 개발이 되어 있다고 해서 6.0을 설치하고 실행을 해봤습니다.&lt;/p&gt; &lt;p&gt;장치관리자에 마우스와 키보드가 추가됨을 확인하고 마우스도 이동을 해봤습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;마우스는 단번에 좌표에 이동하는방식이 아닌 자연스럽게 이동되는 형태로 이동이 되는방식이고&lt;/p&gt; &lt;p&gt;거ㅅ게임을 실행하여 테스트를 해보려고 해봤지만 함수 호출부분에서 에러가 리턴이 되네요.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그래서 vb 실행이 가드에서 막는건지 아니면 usb 마우스 컨트롤 부분에서 막히는건지 확인을 위해 autoit 프로그램으로 dll을 호출해보려고 했습니다.&lt;/p&gt; &lt;p&gt;기존에는 autoit 프로그램으로 마우스 이동이 게임중에 가능은했지만 클라이언트 들어오는 순간 좌표가 먹통이 되면고&lt;/p&gt; &lt;p&gt;움직이질 않아서 HID에 관심을 가지게 된거였습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그런데 제가 autoit에서 dll 함수하는데 애를 먹고있습니다...&lt;/p&gt; &lt;p&gt;xxx.dll 120 134 이런식으로 호출을 하면 되는 형식인줄 알았는데 이런 방식으론 안되네요..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;여기서 질문좀 드릴게요.&lt;/p&gt; &lt;p&gt;소스에&lt;/p&gt; &lt;p&gt;Private Declare Function multiply Lib &quot;MyDll.dll&quot; &lt;/p&gt; &lt;p&gt;이런식으로 dll 명과 multiply명의 함수가 선언이 되어있습니다.&lt;/p&gt; &lt;p&gt;그리고 버튼 클릭시 multiply(1, 1) 라고 호출을 하고 있습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;이러한 형태를 autoit이나 autokey에서 활용하려면 어떻게 코딩을해야 되나요?&lt;/p&gt; &lt;p&gt;너무 초보적인 질문인거 같아 창피합니다....ㅠㅠ&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>피부탄</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347909</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347909#comment</comments>			<pubDate>Sat, 18 Apr 2015 19:36:03 +0900</pubDate>
		</item><item>
			<title>혹시 아두이노 dll관련</title>
			<link>https://autolabs.co.kr/board_cFDS08/347795</link>
				<description>&lt;p&gt;제가 현재 ahk로 사용하고 있는 라이브러리는 아두이노.ahk와 시리얼.ahk 두개를 사용하고 있습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;ahk같은 경우 어떤형태로 든 간에 디컴파일이 가능해서...소스 추출이 쉽다는 단점때문에..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;MFC로 한번 변환을 해볼까 하는데...혹시 아두이노 통신 라이브러리 중에서 DLL화 되어 있는것들이 있을까요?&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;아니면 ahk파일을 Lib, Dll같이 변환하는 작업이 가능할까요?&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347795</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347795#comment</comments>			<pubDate>Fri, 17 Apr 2015 14:58:39 +0900</pubDate>
		</item><item>
			<title>hello 아두이노!</title>
			<link>https://autolabs.co.kr/board_cFDS08/347661</link>
				<description>&lt;p&gt;방금 받자마자 조금 코딩을 해보았는데요...&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;생각만큼은 아니지만..Hello를 찍어보았습니다.&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://autolabs.co.kr/files/attach/images/8458/661/347/17cd639f8c1da987c98af0fa5786d608.JPG&quot; alt=&quot;캡처.JPG&quot; width=&quot;578&quot; height=&quot;257&quot; /&gt; &lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style=&quot;text-align: center;&quot;&gt; &lt;iframe width=&quot;480&quot; height=&quot;360&quot; src=&quot;https://www.youtube.com/embed/i54OtCm2dFw?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt; &lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;실행순서는&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;F1키를 누르면 아두이노가 h를 찍어줍니다.&lt;/p&gt; &lt;p&gt;F2키를 누르면 아두이노가 e를 찍어줍니다.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;F3키를 누르면 아두이노가 l를 찍어줍니다.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;F4키를 누르면 아두이노가 o를 찍어줍니다.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;일단은 밑조사한 방법대로..아두이노 스케치(펌)소스를 작성해서 보드에 업로드를 시킵니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;그리고 시리얼 및 아두이노 라이브러리를 이용해서 ahk 소스를 작성하여 컴파일...그리고 실행&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;일단 오늘 목표는 달성한듯 합니다 ㅎ&lt;/p&gt; &lt;p&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347661</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347661#comment</comments>			<pubDate>Thu, 16 Apr 2015 22:32:05 +0900</pubDate>
		</item><item>
			<title>아두이노 환경설정 참고 - 펌</title>
			<link>https://autolabs.co.kr/board_cFDS08/347551</link>
				<description>&lt;p&gt;구글링하다가 좋은 자료를 찾아서 공유해봅니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;기본적으로 아두이노에 처음 접근하시는 분이라면...많은 도움이 될듯합니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://autolabs.co.kr/?module=file&amp;amp;act=procFileDownload&amp;amp;file_srl=347552&amp;amp;sid=24f84ac785908022503944bb4dccf6eb&amp;amp;module_srl=8458&quot;&gt;뻔뻔한 아두이노 ŰƮ 매뉴얼 Ver2-1.pdf&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347551</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347551#comment</comments>			<pubDate>Thu, 16 Apr 2015 09:53:49 +0900</pubDate>
		</item><item>
			<title>오핫 시리얼 통신</title>
			<link>https://autolabs.co.kr/board_cFDS08/347291</link>
				<description>&lt;p&gt;출처 ㅣ&amp;nbsp;&lt;a href=&quot;http://forum.arduino.cc/index.php?topic=128566.0&quot; target=&quot;_blank&quot;&gt;http://forum.arduino.cc/index.php?topic=128566.0&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;아두이노와 오핫과의 시리얼 통신부분을 좀 찾아봤는데요..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;혹시 여기서 이야기하는 스케치 스크립트라는것이 Firm 소스를 얘기하는건가요?&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;ahk 스크립트 :&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;table style=&quot;background:#CCCCCC;border-spacing:1px&quot; cellspacing=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr style=&quot;background:#F7E2D2&quot;&gt;&lt;td&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; AutoHotkey Version: 1.x&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; Language:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;English&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; Platform:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Windows XP +??&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; Author:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ahklerner / kruzan&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; Script Function:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;box-sizing: border-box; color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;Arduino GUI Example&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; set some defaults&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;#NoEnv&amp;nbsp; ; Recommended for performance and compatibility with future AutoHotkey releases.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;SendMode Input&amp;nbsp; ; Recommended for new scripts due to its superior speed and reliability.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;SetWorkingDir %A_ScriptDir%&amp;nbsp; ; Ensures a consistent starting directory.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; serial settings&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ARDUINO_Port&amp;nbsp; &amp;nbsp; &amp;nbsp;= COM10&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ARDUINO_Baud&amp;nbsp; &amp;nbsp; &amp;nbsp;= 9600&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ARDUINO_Parity&amp;nbsp; &amp;nbsp;= N&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ARDUINO_Data&amp;nbsp; &amp;nbsp; &amp;nbsp;= 8&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ARDUINO_Stop&amp;nbsp; &amp;nbsp; &amp;nbsp;= 1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; setup arduino serial communication&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;arduino_setup(start_polling_serial:=false)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; *****************GUI CODE***************&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;^s::&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;arduino_send(&quot;on&quot;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;*************************************************************************************&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; *****Do not edit below this line unless you want to change the core functionality of the script*****&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;*************************************************************************************&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; called when the gui is closed&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;;also called when program exits&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;GuiClose:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;OnExit:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;box-sizing: border-box; color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; make sure to cleanly shut down serial port on exit&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;box-sizing: border-box; color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;arduino_close()&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;; this is important!! or else theprogram does not end when closed&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;ExitApp&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;#include %A_ScriptDir%\include\Arduino.ahk&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;아두이노 스케치(Firm?) 스크립트 :&amp;nbsp;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;table style=&quot;background:#CCCCCC;border-spacing:1px&quot; cellspacing=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr style=&quot;background:#EDF2C2&quot;&gt;&lt;td&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;/*&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; Blink&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; Turns on an LED on for one second, then off for one second, repeatedly.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; This example code is in the public domain.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;// Pin 13 has an LED connected on most Arduino boards.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;// give it a name:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;char serialIn[20];&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;char holder = -1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;// the setup routine runs once when you press reset:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;void setup() {&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; // initialize the digital pin as an output.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; pinMode(8, OUTPUT);&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;digitalWrite(8, LOW);&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; pinMode(9, OUTPUT);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; Serial.begin(9600);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;// the loop routine runs over and over again forever:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;void loop() {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; int index = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; while (Serial.available() &amp;gt; 0)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; &amp;nbsp; if (index &amp;lt; 19)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; holder = Serial.read();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; serialIn[index] = holder;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;index++;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; serialIn[index] = &#039;\0&#039;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; Serial.println(serialIn);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; if (strcmp(serialIn, &quot;on&quot;) == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; digitalWrite(9, HIGH);&amp;nbsp; &amp;nbsp;// turn the LED on (HIGH is the voltage level)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; delay(1000);&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// wait for a second&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; digitalWrite(9, LOW);&amp;nbsp; &amp;nbsp; // turn the LED off by making the voltage LOW&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; delay(1000);&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// wait for a second&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(34, 34, 34); font-family: &#039;DejaVu Sans Mono&#039;, Monaco, Consolas, monospace; font-size: 13.2294721603394px; line-height: 20.5791778564453px; white-space: nowrap; background-color: rgb(255, 255, 255);&quot;&gt;}&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://forum.arduino.cc/index.php?topic=128566.0&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347291</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347291#comment</comments>			<pubDate>Tue, 14 Apr 2015 17:14:21 +0900</pubDate>
		</item><item>
			<title>USB-Keyboard, Mouse 에뮬레이션 하기 - 펌</title>
			<link>https://autolabs.co.kr/board_cFDS08/347206</link>
				<description>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;출처 :&amp;nbsp;&lt;a href=&quot;http://arduinomidi.com/xe/BlogBoard/40820&quot; target=&quot;_blank&quot;&gt;http://arduinomidi.com/xe/BlogBoard/40820&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;rd_hd clear&quot; data-url=&quot;http://arduinomidi.com/xe/40820&quot; style=&quot;margin: 0px 0px 60px; padding: 0px; position: relative; clear: both; color: rgb(68, 68, 68); font-family: &#039;Segoe UI&#039;, Meiryo, 나눔고딕, NanumGothic, ng, &#039;맑은 고딕&#039;, &#039;Malgun Gothic&#039;, 돋움, Dotum, AppleGothic, sans-serif; font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;div class=&quot;blog v&quot; style=&quot;margin: 0px; padding: 13px 22.875px; border-top-width: 3px; border-top-style: solid; border-top-color: rgb(51, 51, 51); border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(102, 102, 102);&quot;&gt;&lt;h1 class=&quot;font ngeb&quot; style=&quot;margin: 0.85em 4px 1em; padding: 0px; font-size: 2.3em; letter-spacing: -1px; line-height: 1; font-family: &#039;Segoe UI&#039;, Meiryo, &#039;나눔고딕 ExtraBold&#039;, &#039;NanumGothic ExtraBold&#039;, ngeb, &#039;맑은 고딕&#039;, &#039;Malgun Gothic&#039;, 나눔고딕, NanumGothic, ng, &#039;Trebuchet MS&#039;, 돋움, dotum, AppleGothic, sans-serif; -webkit-text-stroke-width: 0.25px; -webkit-animation-duration: 2s; -webkit-animation-timing-function: ease-in-out; -webkit-animation-name: rd_h1_v;&quot;&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;아두이노 &quot; style=&quot;width: 120px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;레오나르도 &quot; style=&quot;width: 146px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;163&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 163px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;활용 &quot; style=&quot;width: 66px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;83&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 83px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;- &quot; style=&quot;width: 28px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;45&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 45px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;3. &quot; style=&quot;width: 37px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;54&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 54px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;USB-Keyboard, &quot; style=&quot;width: 222px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;238&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 238px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;Mouse &quot; style=&quot;width: 101px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;118&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 118px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;에뮬레이션 &quot; style=&quot;width: 146px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;163&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 163px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;cufon class=&quot;cufon cufon-canvas&quot; alt=&quot;하기&quot; style=&quot;width: 54px; height: 29.8999996185303px; display: inline-block !important; position: relative !important; vertical-align: middle !important; font-size: 1px !important; line-height: 1px !important;&quot;&gt;&lt;canvas width=&quot;56&quot; height=&quot;30&quot; style=&quot;position: relative !important; width: 56px; height: 30px; top: 0px; left: 0px;&quot;&gt;&lt;/canvas&gt;&lt;cufontext style=&quot;display: inline-block !important; width: 0px !important; height: 0px !important; overflow: hidden !important; text-indent: -10000in !important;&quot;&gt;&lt;/cufontext&gt;&lt;/cufon&gt;&lt;/h1&gt;&lt;div class=&quot;btm_area ngeb np_18px&quot; style=&quot;margin: 0px; padding: 0px; font-weight: bold; font-family: &#039;Segoe UI&#039;, Meiryo, &#039;나눔고딕 ExtraBold&#039;, &#039;NanumGothic ExtraBold&#039;, ngeb, &#039;맑은 고딕&#039;, &#039;Malgun Gothic&#039;, 나눔고딕, NanumGothic, ng, &#039;Trebuchet MS&#039;, 돋움, dotum, AppleGothic, sans-serif;&quot;&gt;&lt;span style=&quot;padding: 0px 6px 16px; font-size: 12px; color: rgb(119, 119, 119); display: inline-block; text-shadow: rgba(0, 0, 0, 0.0784314) 0px 1px 0px;&quot;&gt;&lt;small style=&quot;color: rgb(170, 170, 170); padding-right: 2px; font-weight: normal; font-style: italic; font-size: 12px;&quot;&gt;by&amp;nbsp;&lt;/small&gt;&lt;strong style=&quot;letter-spacing: 0px;&quot;&gt;Kody&lt;/strong&gt;&lt;/span&gt; &lt;span title=&quot;2013.12.05 15:28&quot; style=&quot;padding: 0px 6px 16px; font-size: 12px; color: rgb(119, 119, 119); display: inline-block; text-shadow: rgba(0, 0, 0, 0.0784314) 0px 1px 0px;&quot;&gt;&lt;small style=&quot;color: rgb(170, 170, 170); padding-right: 2px; font-weight: normal; font-style: italic; font-size: 12px;&quot;&gt;posted&amp;nbsp;&lt;/small&gt;&lt;strong class=&quot;date&quot; style=&quot;letter-spacing: 0px; font-variant: small-caps; font-size: 1em;&quot;&gt;Dec 05, 2013&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;padding: 0px 6px 16px; font-size: 12px; color: rgb(119, 119, 119); display: inline-block; text-shadow: rgba(0, 0, 0, 0.0784314) 0px 1px 0px;&quot;&gt;&lt;small style=&quot;color: rgb(170, 170, 170); padding-right: 2px; font-weight: normal; font-style: italic; font-size: 12px;&quot;&gt;Replies&lt;/small&gt;&amp;nbsp;&lt;strong style=&quot;letter-spacing: 0px;&quot;&gt;2&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;rd_nav img_tx fr m_btn_wrp&quot; style=&quot;margin: 15px 11px 0px; padding: 0px; float: right; position: relative; border: 1px solid rgb(211, 211, 211); border-radius: 4px; background: rgb(252, 252, 252);&quot;&gt;&lt;div class=&quot;help bubble left m_no&quot; style=&quot;margin: 0px; padding: 0px; position: relative; float: left; cursor: help;&quot;&gt;&lt;a class=&quot;text&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; style=&quot;outline: none; text-decoration: none; color: rgb(153, 153, 153); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; display: inline-block; width: 16px; font-weight: bold; font-family: Georgia, &#039;Times New Roman&#039;, Times, serif; text-align: center; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;?&lt;/a&gt;&lt;/div&gt;&lt;a class=&quot;font_plus bubble&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; title=&quot;크게&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-zoomin&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -128px -112px; background-repeat: no-repeat;&quot;&gt;+&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;font_minus bubble&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; title=&quot;작게&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-zoomout&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -144px -112px; background-repeat: no-repeat;&quot;&gt;-&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#bd&quot; title=&quot;위로&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-arrow-1-n&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: 0px -32px; background-repeat: no-repeat;&quot;&gt;Up&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#rd_end_40820&quot; title=&quot;(목록) 아래로&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-arrow-1-s&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -64px -32px; background-repeat: no-repeat;&quot;&gt;Down&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;comment back_to bubble if_viewer m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#comment&quot; title=&quot;댓글로 가기&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-comment&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -128px -96px; background-repeat: no-repeat;&quot;&gt;Comment&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;print_doc bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/index.php?mid=BlogBoard&amp;amp;document_srl=40820&amp;amp;listStyle=viewer&quot; title=&quot;인쇄&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-print&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -160px -96px; background-repeat: no-repeat;&quot;&gt;Print&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;file back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#files_40820&quot; title=&quot;첨부파일&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-disk&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -96px -112px; background-repeat: no-repeat;&quot;&gt;Files&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;rd_nav_side m_no&quot; style=&quot;margin: 0px; padding: 0px; position: absolute; z-index: 100; right: 0px;&quot;&gt;&lt;div class=&quot;rd_nav img_tx fr m_btn_wrp&quot; style=&quot;margin: 0px; padding: 0px; float: right; position: fixed; border: 1px solid rgb(211, 211, 211); border-radius: 4px; bottom: 13px; width: 28px; background: rgb(252, 252, 252);&quot;&gt;&lt;div class=&quot;help bubble left m_no&quot; style=&quot;margin: 0px; padding: 0px; position: relative; float: left; cursor: help;&quot;&gt;&lt;a class=&quot;text&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; style=&quot;outline: none; text-decoration: none; color: rgb(153, 153, 153); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; display: inline-block; width: 16px; font-weight: bold; font-family: Georgia, &#039;Times New Roman&#039;, Times, serif; text-align: center; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;?&lt;/a&gt;&lt;/div&gt;&lt;a class=&quot;font_plus bubble&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; title=&quot;크게&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-zoomin&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -128px -112px; background-repeat: no-repeat;&quot;&gt;+&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;font_minus bubble&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#&quot; title=&quot;작게&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-zoomout&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -144px -112px; background-repeat: no-repeat;&quot;&gt;-&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#bd&quot; title=&quot;위로&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-arrow-1-n&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: 0px -32px; background-repeat: no-repeat;&quot;&gt;Up&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#rd_end_40820&quot; title=&quot;(목록) 아래로&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-arrow-1-s&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -64px -32px; background-repeat: no-repeat;&quot;&gt;Down&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;comment back_to bubble if_viewer m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#comment&quot; title=&quot;댓글로 가기&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-comment&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -128px -96px; background-repeat: no-repeat;&quot;&gt;Comment&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;print_doc bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/index.php?mid=BlogBoard&amp;amp;document_srl=40820&amp;amp;listStyle=viewer&quot; title=&quot;인쇄&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-print&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -160px -96px; background-repeat: no-repeat;&quot;&gt;Print&lt;/strong&gt;&lt;/a&gt;&lt;a class=&quot;file back_to bubble m_no&quot; href=&quot;http://arduinomidi.com/xe/BlogBoard/40820#files_40820&quot; title=&quot;첨부파일&quot; style=&quot;outline: none; position: relative; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s; float: left; padding: 6px; font-size: 12px; line-height: 16px; letter-spacing: -1px;&quot;&gt;&lt;strong class=&quot;ui-icon ui-icon-disk&quot; style=&quot;display: inline-block; text-indent: -100px; overflow: hidden; width: 16px; height: 16px; letter-spacing: 0px; font-size: 0px; line-height: 0; vertical-align: top; transition: all 0.3s; -webkit-transition: all 0.3s; background-image: url(http://arduinomidi.com/xe/common/js/plugins/ui/images/ui-icons_888888_256x240.png); background-position: -96px -112px; background-repeat: no-repeat;&quot;&gt;Files&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;rd_body clear&quot; style=&quot;margin: 0px 0px 30px; padding: 0px; position: relative; clear: both; color: rgb(68, 68, 68); font-family: &#039;Segoe UI&#039;, Meiryo, 나눔고딕, NanumGothic, ng, &#039;맑은 고딕&#039;, &#039;Malgun Gothic&#039;, 돋움, Dotum, AppleGothic, sans-serif; font-size: 13px; line-height: 19.5px;&quot;&gt;&lt;div class=&quot;document_40820_1645 xe_content&quot; style=&quot;margin: 0px; padding: 0px; font-size: 13px;&quot;&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;1. 아두이노 레오나르도 특징&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;2. 아두이노 보드의 차이점 정리&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;&lt;font color=&quot;#ff0000&quot;&gt;3. USB-Keyboard, Mouse 에뮬레이션 하기&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;4. 레오나르도 부트로더를 이용하여 Atmel Studio에서 만든 펌웨어를 올리기&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;5. USB-Joystick 에뮬레이션 하기&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;6. USB-MIDI 사용하기&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;7. C#과 통신하여 LED 깜빡이고 스위치값 읽어오기&lt;/strong&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;strong&gt;8. RN42를 이용하여 무선 블루투스아이패드와 안드로이드 게임 콘트롤러 만들기&lt;/strong&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;font size=&quot;4&quot; face=&quot;Tahoma, sans-serif&quot;&gt;&lt;span style=&quot;line-height: 27px;&quot;&gt;&lt;strong&gt;아두이노 레오나르도 USB라이브러리 기능&lt;/strong&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt; &lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 19px;&quot;&gt;아두이노 레오나르도와 아두이노 우노의 가장 큰 차이점이라면 아두이노 레오나르도에는 USB라이브러리 기능이 기본 탑재되어 있다는 점 입니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;이 라이브러리는 사용자가 쉽게 아두이노 레오나르도을 사용하여 키보드나 마우스를 에뮬레이트 할 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;사용자가 아두이노 IDE는 기본적으로 USB 키보드, 마우스 기능을 탑재하고 있어, 아두이노 레오나르도에서 키보드나 마우스 기능을 사용할 수 있습니다. 기본 키보드 및 마우스 에뮬레이션 명령 중 일부를 아래에 설명 합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: large; font-family: Tahoma, sans-serif; line-height: 27px; background-color: rgb(255, 255, 255);&quot;&gt;마우스&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 19px;&quot;&gt;&lt;strong&gt;Mouse.begin() 과 Mouse.end()&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;begin()함수는 마우스 라이브러리를 초기화 하고 시작 합니다. 이것으로 레오나르도가 마우스로 작동을 시작 할 수 있습니다. end() 함수는 마우스 에뮬레이션을 중지합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Mouse.click()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;click()함수는 마우스의 클릭 기능 입니다. 기본적으로 마우스의 왼쪽 버튼 클릭을 에물레이션 하며, 인수로 다른 버튼 클릭 동작을 실행 할 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;MOUSE_LEFT – 마우스 왼쪽 버튼을 클릭 합니다.&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;MOUSE_RIGHT – 마우스 오른쪽 버튼을 클릭 합니다.&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;MOUSE_MIDDLE – 마우스 중앙 버튼을 클릭 합니다.&lt;/blockquote&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Mouse.move()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;Move() 함수는 레오나르도가 화면에 마우스 커서의 위치를 제어 하는데 사용 합니다. 이 함수는 3개의 정수타입 인수가 필요 합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;xVal – X축으로 마우스 포인터가 이동할 양을 정의 합니다.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;yVal – Y축으로 마우스 포인터가 이동할 양을 정의 합니다.&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;wheel – 휠스크롤에서 크롤될 값을 정의 합니다.&lt;/blockquote&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Mouse.press() 와 &amp;nbsp;Mouse.release()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;press()함수는 click() 함수와 비슷하게 작동합니다. 그러나 press()함수는 release()함수가 호출 되기전 까지, 선택된 버튼을 계속 누르고 있는 동작을 하게 됩니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;press() 및 release()함수는 기본족으로 마우스 왼쪽 버튼을 기본값으로 하지만, click() 함수처럼 인수를 통해 동작할 버튼을 지정 할 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Mouse.isPressed()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;isPressed() 함수는 해당버튼을 누르면 bool 값 (true 또는 false)을 반환 합니다. 기본적으로 왼쪽 버튼이 선택 되어 있지만, press(), release(), click()함수와 같이 인수를 통해서 동작할 버튼을 지정 할 수 있습니다. 이 함수로 해당버튼이 눌려 있는지 여부를 판별해 낼 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: large; font-family: Tahoma, sans-serif; line-height: 27px; background-color: rgb(255, 255, 255);&quot;&gt;키보드&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 19px;&quot;&gt;&lt;strong&gt;Keyboard.begin() 과 Keyboard.end()&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;키보드 라이브러리의 begin()과 end()함수는 마우스 라이브러리와 마찬가지로 키보드 에물레이션의 동작과 정지 기능을 가집니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Keyboard.press() 와 Keyboard.release()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;press() 및 release() 함수는 마우스 라이브러리에 있는 해당 함수와 유사하게 작동합니다. 그러나 사용자가 문자 인수를 전달하여 누르거나(press) 해제(release)되는 키를 지정할 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Keyboard.print()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;print() 함수는 컴퓨터에 키 입력을 전송하는 데 사용됩니다. 매개 변수로, 함수는 문자나 문자열을 전달 할 수 있습니다.&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Keyboard.println()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;println() 함수는 print() 함수와 유사하게 작동합니다. 그러나 println() 함수는 문자를 표시하고 항상 캐리지 리턴을 수행하여 끝에 새 줄을 시작합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Keyboard.releaseAll()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;releaseAll() 함수는 release() 함수와 유사하게 동작 합니다. 그러나 눌러져 있는 모든 키를 한번에 &amp;nbsp;해제합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;Keyboard.write()&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;Write() 함수는 문자키를 포함하여 컴퓨터의 모든 키 입력을 보낼 수 있습니다. &amp;nbsp;이를테면 백스페이스, 콘트롤, ALT, 펑션키등을 보냘 수 있습니다. write() 의 인수로 정수(ASCII), 문자, HEX, 이진값등 으로 보낼 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: large; font-family: Tahoma, sans-serif; line-height: 27px; background-color: rgb(255, 255, 255);&quot;&gt;라이브러리 예제&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 19px;&quot;&gt;이번 항목 에서는 키보드와 마우스 라이브러리를 사용 하는 간단한 예제 프로그램을 소개하고 가능을(주석참조) 설명합니다. 참고로 이 예제는 아두이노 공식 사이트에 올라와 있는 예제 입니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;a href=&quot;http://arduino.cc/en/Tutorial/KeyboardAndMouseControl&quot; target=&quot;_blank&quot; style=&quot;outline: none; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s;&quot;&gt;http://arduino.cc/en/Tutorial/KeyboardAndMouseControl&lt;/a&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;회로구성&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;1. 아두이노 레오나르도의 디지털 입력핀 2, 3, 4, 5, 6번핀에 푸시버튼의 한쪽 끝을 연결 합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;2. 버튼의 다른쪽 끝은 5V에 연결 합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;3. 아래의 그림을 참조하여 아두이노 각 핀에 연결되어 있는 푸시버튼에 10K 저항을 연결하고 저항의 반대쪽은 모두 그라운드에 연결 합니다. 이 같은 연결 형태를 풀다운 스위치라고 합니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;img src=&quot;http://cafeptthumb2.phinf.naver.net/20130709_163/pasil21_1373306945671L4JDb_PNG/LeoJoystickTest_bb.png?type=w740&quot; alt=&quot;&quot; rel=&quot;xe_gallery&quot; style=&quot;height: 397px; width: 740px;&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://arduinomidi.com/xe/files/attach/images/110/820/040/ac8552e160345d7137274580983fd745.png&quot; alt=&quot;LeoJoystickTest_schem.png&quot; class=&quot;iePngFix&quot; width=&quot;740&quot; height=&quot;594&quot; rel=&quot;xe_gallery&quot; style=&quot;cursor: pointer;&quot; /&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;회로동작&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;문서편집기를 이용하여 소스를 입력하고, 아두이노 레오나르도 보드를 USB로 연결 한 다음에, 아두이노 소프트웨어를 통해 업로드를 합니다. 정상적으로 업로드가 되면, 푸시버튼을 눌렀을 때 해당되는 키값이 입력되는 것을 볼 수 있으며, 시리얼 모니터창을 띄우고 해당문자를 입력하면 마우스 포인터가 움직이는 것을 확인 할 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;프로그램 소스&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 아두이노의 핀을 초기화 하고 각각의 버튼에 해당하는 기능을 할당 합니다.&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;const int upButton = 2;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;const int downButton = 3;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;const int leftButton = 4;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;const int rightButton = 5;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;const int mouseButton = 6;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;void setup() {&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;&amp;nbsp; &amp;nbsp; // 각각의 핀을 입력모드로 지정 합니다.&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; pinMode(upButton, INPUT); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; pinMode(downButton, INPUT); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; pinMode(leftButton, INPUT); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; pinMode(rightButton, INPUT); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; pinMode(mouseButton, INPUT);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 시리얼 모니터의 보레이트를 설정 합니다.&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; Serial.begin(9600);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 키보드와 마우스 라이브러리를 초기화 합니다.&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; Mouse.begin();&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; Keyboard.begin();&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;}&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;void loop() {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 마우스 제어를 위해 가상 시리얼 포트를 사용하여 명령을 내립니다.&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (Serial.available() &amp;gt; 0) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; char inChar = Serial.read();&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 입력받은 문자를 검사하여 해당하는 문자에 대한 마우스 동작을 수행 합니다.&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; switch (inChar) { &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &#039;u&#039;:&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // move mouse up&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Mouse.move(0, -40);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &#039;d&#039;:&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // move mouse down&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Mouse.move(0, 40);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &#039;l&#039;:&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // move mouse left&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Mouse.move(-40, 0);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &#039;r&#039;:&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // move mouse right&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Mouse.move(40, 0);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &#039;m&#039;:&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // perform mouse left click&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Mouse.click(MOUSE_LEFT);&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: rgb(0, 117, 200);&quot;&gt;// 푸시버튼의 상태를 입력 받아 값이 HIGH일 때 지정된 문자를 컴퓨터에 전송 합니다.&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (digitalRead(upButton) == HIGH) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard.write(&#039;u&#039;);&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (digitalRead(downButton) == HIGH) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard.write(&#039;d&#039;);&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (digitalRead(leftButton) == HIGH) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard.write(&#039;l&#039;);&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (digitalRead(rightButton) == HIGH) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Keyboard.write(&#039;r&#039;);&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; if (digitalRead(mouseButton) == HIGH) {&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Keyboard.write(&#039;m&#039;);&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: large; font-family: Tahoma, sans-serif; line-height: 27px; background-color: rgb(255, 255, 255);&quot;&gt;키보드 라이브러리 응용&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 19px;&quot;&gt;다음예제는 조이스틱과 푸시버튼의 값을 읽어 들여, 조이스틱은 키보드의 커서키를 에물레이션하고, 버튼은 업다운키를 에물레이션하여 CNC설비를 제어하는 예제 입니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;먼저 간단한 동영상을 보도록 하겠습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px; text-align: center;&quot;&gt;&lt;iframe height=&quot;360&quot; src=&quot;http://www.youtube.com/embed/ShjVWER3CGM?feature=player_detailpage&quot; frameborder=&quot;0&quot; width=&quot;640&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;span style=&quot;font-size: 12px; line-height: 1.5;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;p style=&quot;padding: 0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;padding: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;회로구성&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;보다 많은 버튼을 사용할 목적으로 아두이노 9핀(아두이노핀 5, 6, 7, 8번 입력, 9, 10, 11, 12, 13번 출력)을 이용하여, 총 20개의 버튼 입력을 받을 수 있도록 한 전형적인 키 매트릭스 회로 입니다. 예제 에서는 키 입력을 모두 사용하지 않고, 조이스틱 4개, 푸시버튼 8개, 확장버튼 2개 총 14개의 버튼 입력을 사용 합니다. 회로에서 사용된 저항은 모두 10K(풀업저항)이며, 다이오드는 1N4148 입니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;img src=&quot;http://cafeptthumb2.phinf.naver.net/20130709_194/pasil21_1373306989483Mx3LX_PNG/MatrixSch.png?type=w740&quot; alt=&quot;&quot; rel=&quot;xe_gallery&quot; style=&quot;height: 140px; width: 740px;&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;버튼에 따른 기능은 아래와 같습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 1번 : 문자 ‘a’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 2번 : 문자 ‘b’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 3번 : 문자 ‘c’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 4번 : 키보드 페이지업&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 5번 : 문자 ‘d’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 6번 : 문자 ‘e’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 7번 : 문자 ‘f’&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 8번 : 키보드 페이지 다운&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼 9번~16번 : 사용안함&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼17번 : 키보드 왼쪽&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼18번 : 키보드 오른쪽&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼19번 : 키보드 위&lt;/blockquote&gt;&lt;blockquote style=&quot;margin: 0px 0px 0px 40px; padding: 0px; border-style: none;&quot;&gt;버튼20번 : 키보드 아래&lt;/blockquote&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 1.5;&quot;&gt;&lt;strong&gt;회로동작&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;메트릭스 버튼 입력 하는 방법은 읽어올 칼럼의 라인만 LOW로 하고 나머지 칼럼의 라인은 모두 HIGH로 둡니다. 그렇게 하면 해당하는 라인의 값만 읽어 올 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;이렇게 순차적으로 루프를 돌리면서 칼럼 라인을 변경하면 할당한 모든 버튼의 값을 읽어 올 수 있습니다. 워낙 빠른 속도로 순차적으로 읽기 때문에 사용자 입장에서는 버튼의 입력이 동시에 되는 듯한 효과를 볼 수 있습니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;이렇게 순차적으로 버튼의 값을 입력 받아, 해당하는 버튼에 지정된 키보드 값을 컴퓨터에 보내주고, 시리얼 모니터 창에 입력 받은 값을 표시 하게 됩니다.&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;프로그램 소스&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;http://arduinomidi.com/xe/?module=file&amp;amp;act=procFileDownload&amp;amp;file_srl=5318&amp;amp;sid=591024e301f8bea7d0a033e3f5fd14d9&quot; target=&quot;_blank&quot; style=&quot;outline: none; text-decoration: none; color: rgb(51, 51, 51); transition: all 0.4s; -webkit-transition: all 0.4s;&quot;&gt;Leonardo_bCade_CNC.ino&lt;/a&gt;&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: large; font-family: Tahoma, sans-serif; line-height: 27px; background-color: rgb(255, 255, 255);&quot;&gt;마치며&lt;/strong&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;hr style=&quot;border-style: solid; font-size: 12px; font-family: Tahoma, sans-serif; border-color: green; line-height: 18px; background-color: rgb(255, 255, 255);&quot; /&gt;&lt;p style=&quot;padding: 0px; font-size: 12px; font-family: Tahoma, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;font-size: small; line-height: 1.5;&quot;&gt;이번 회에 소개된 회로와 소스를 이용하면 자신만의 콘트롤러, 즉 마메게임 콘트롤러라던가 비행 시뮬 콘트롤러, 로봇팔 제어기등, 다양하게 응용 가능하리라 생각이 듭니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;font size=&quot;2&quot;&gt;다음시간에는 아두이노 레오나르도의 부트로더를 이용하여, 아두이노가 아닌, Atmel Studio 등에서만들어진 네이티브 펌웨어를 업로드 하는 방법에 대해 알아 보도록 하겠습니다.&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347206</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347206#comment</comments>			<pubDate>Mon, 13 Apr 2015 17:54:10 +0900</pubDate>
		</item><item>
			<title>드라이버 라이센스 관련..</title>
			<link>https://autolabs.co.kr/board_cFDS08/347127</link>
				<description>&lt;p&gt;방금들은 정보지만..혹 도움이 될까하여..올려봅니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;VHID 같은 경우 드라이버를 가상으로 제작을 해야 되는걸로 알고 있습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;근데 이 드라이버 라는걸 만들어 사용하기 위해서는 MS에 등록을 하고 인증을 받아야 한다더군요...&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;등록하는것 까지는 이해가 되는데...비용을 지불해야 된다는 정보가 있네요...&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;더 자세한건 더 찾아봐야 겠지만...정보를 계속 업데이트 해야 겠습니다 ㅎ&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347127</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347127#comment</comments>			<pubDate>Fri, 10 Apr 2015 17:32:22 +0900</pubDate>
		</item><item>
			<title>VHID 개발 환경 설정중입니다.</title>
			<link>https://autolabs.co.kr/board_cFDS08/347108</link>
				<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;제가 알아본 결과 초기 설정은 VB + WDK8 로 시작하는거 같습니다. 언어는 C++ 인거같고&lt;/p&gt; &lt;p&gt;WDK 8버전은 윈8, 윈7도 호환이 되는걸로 알고잇습니다.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;근데 집에서 VB가 설치중에 에러가 납니다.&lt;/p&gt; &lt;p&gt;결론은 아무것도 한게없습니다.....&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=26&amp;amp;MAEULNo=11&amp;amp;no=9521&amp;amp;ref=9521&quot;&gt;http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=26&amp;amp;MAEULNo=11&amp;amp;no=9521&amp;amp;ref=9521&lt;/a&gt;&lt;/p&gt; &lt;p&gt;이 글을 보면 VB 설치하고 WDK 설치하면 자동으로 설정이 된다고 하네요&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;근데 우리집에서는 VB안깔렸습니다..&lt;br /&gt;&lt;/p&gt; &lt;p&gt;해본것도 없이 어제 하루가 끝났습니다..&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;설치하려는게 VB2013 버전인데 2012 버전으로 내릴까 생각중입니다.&lt;br /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>피부탄</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/347108</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/347108#comment</comments>			<pubDate>Fri, 10 Apr 2015 09:59:53 +0900</pubDate>
		</item><item>
			<title>DDK (Driver Developer Kit) and WDK (Windows Driver Kit)</title>
			<link>https://autolabs.co.kr/board_cFDS08/345091</link>
				<description>&lt;p data-iceapw=&quot;13&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;13&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;13&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px; color: rgb(204, 0, 0);&quot;&gt;&lt;span data-iceapw=&quot;13&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;DDK (Driver&amp;nbsp;Developer Kit) and WDK (Windows&amp;nbsp;Driver&amp;nbsp;Kit) the difference between:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;13&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;13&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;13&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px; color: rgb(204, 0, 0);&quot;&gt;&lt;span data-iceapw=&quot;13&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;7&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;7&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;This to talk about driving some history:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;7&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;7&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;span data-iceapw=&quot;7&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;33&quot; data-iceapc=&quot;3&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;33&quot; data-iceapc=&quot;2&quot;&gt;&lt;span data-iceapw=&quot;33&quot; data-iceapc=&quot;1&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;span data-iceapw=&quot;17&quot; style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;1) .95/98/ME driven model: VXD, you can see the first few chapters of &quot;programming expert Proverbs,&lt;/span&gt;&amp;nbsp;there are very detailed introduction, this thing is outdated, but probably look still increase their knowledge.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;16&quot; data-iceapc=&quot;2&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;16&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;16&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;16&quot; data-iceapc=&quot;2&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;16&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;16&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;2) .2000/XP/2003 under Windows WDM&amp;nbsp;driver&amp;nbsp;model (Windows&amp;nbsp;Driver&amp;nbsp;Model)&amp;nbsp;driverdevelopment kit development 2000/XP/2003: DDK.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;19&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;19&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;19&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;19&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;3) Vista and later, using the WDF&amp;nbsp;driver&amp;nbsp;model (Windows&amp;nbsp;Driver&amp;nbsp;Foudation), corresponding to the open contract: the WDK.&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;In fact, the WDK can be seen as an upgraded version of the DDK, general WDK contains DDK-related functions, XP can also be developed with WDK&amp;nbsp;driver, the WDK to compile various&amp;nbsp;&lt;span id=&quot;IL_AD4&quot; class=&quot;IL_AD&quot; style=&quot;position: static; border-bottom-width: 1px !important; border-bottom-style: dotted !important; border-bottom-color: rgb(3, 108, 155) !important; color: rgb(3, 108, 155) !important; cursor: pointer !important; display: inline !important; padding: 0px 0px 1px !important; float: none !important; background-image: none !important; background-attachment: scroll !important; background-size: initial !important; background-origin: initial !important; background-clip: initial !important; background-position: 0% 50%; background-repeat: repeat !important;&quot;&gt;drivers&lt;/span&gt;&amp;nbsp;of 2000-2008.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;----------------------------------------------------------------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;h5 style=&quot;margin: 1.714285714rem 0px; padding: 0px; border: 0px; font-size: 0.928571429rem; vertical-align: baseline; clear: both; font-family: &#039;Nanum Gothic&#039;; line-height: 24px; color: rgb(68, 68, 68); background-color: rgb(255, 255, 255);&quot;&gt;Windows Driver Kit&lt;/h5&gt;&lt;p style=&quot;margin-bottom: 1.714285714rem; padding: 0px; border: 0px; font-size: 14px; vertical-align: baseline; font-family: &#039;Nanum Gothic&#039;; line-height: 24px; color: rgb(68, 68, 68); background-color: rgb(255, 255, 255);&quot;&gt;WDK는 윈도용 디바이스 드라이버를 개발하는 데 쓰는 도구다. 서버 2003 이전에는 DDK(&lt;a href=&quot;http://www.microsoft.com/whdc/devtools/ddk/default.mspx&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; outline: none; color: rgb(159, 159, 159);&quot;&gt;Driver Development Kit&lt;/a&gt;)라고 불렀는데, Windows Driver Foundation(WDF)과 Installable File Systems (IFS) Kit를 통합하면서 비스타부터는 WDK로 이름이 바뀌었다. WDK 안에는 C++ 컴파일러와 빌드에 필요한 도구가 모두 들어있어서 VS 없이도 드라이버를 개발할 수 있게 되어 있다. 그런데 실제로는 VS를 안쓰고 프로그램을 개발하려니 환경이 엄청나게 열악하다. 자세한 얘기는 나중에 하고, DDK/WDK와 들어 있는 C++ 컴파일러와의 버전 관계는 다음과 같다:&lt;/p&gt; &lt;p data-iceapw=&quot;54&quot; data-iceapc=&quot;4&quot; style=&quot;color: rgb(102, 102, 102); font-family: Arial, Helvetica, sans-serif; font-size: 13.3333330154419px; line-height: 20px; text-align: justify;&quot;&gt;&lt;span data-iceapw=&quot;35&quot; data-iceapc=&quot;1&quot;&gt;&lt;span data-iceapw=&quot;35&quot; style=&quot;font-family: System; font-size: 18px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin-bottom: 1.714285714rem; padding: 0px; border: 0px; font-size: 14px; vertical-align: baseline; font-family: &#039;Nanum Gothic&#039;; line-height: 24px; color: rgb(68, 68, 68); background-color: rgb(255, 255, 255);&quot;&gt;&lt;img border=&quot;0&quot; alt=&quot;wdk&quot; src=&quot;http://cfs8.tistory.com/upload_control/download.blog?fhandle=YmxvZzE5MjUwQGZzOC50aXN0b3J5LmNvbTovYXR0YWNoLzAvMTkwMDAwMDAwMDAwLnBuZw%3D%3D&quot; width=&quot;570&quot; height=&quot;109&quot; style=&quot;margin: 0px; padding: 0px; vertical-align: baseline; border-radius: 3px; box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 4px;&quot; /&gt;&lt;/p&gt;</description>
		<category>입력 제어</category>	<category>팁/강의</category>				<dc:creator>오토소장</dc:creator>
			<guid isPermaLink="true">https://autolabs.co.kr/board_cFDS08/345091</guid>
	<comments>https://autolabs.co.kr/board_cFDS08/345091#comment</comments>			<pubDate>Wed, 25 Mar 2015 11:56:26 +0900</pubDate>
		</item>	</channel>
</rss>
