URL 할당 및 빌드
USB 클라이언트 드라이버는 Microsoft에서 제공하는 USB 드라이버 스택에 요청을 보내기 전에 WDM(Windows 드라이버 모델) 드라이버 루틴을 사용하여 URB를 할당하고 포맷할 수 있습니다.
클라이언트 드라이버는 URB를 사용하여 요청을 처리하기 위해 USB 드라이버 스택의 하위 드라이버에 필요한 모든 정보를 패키지합니다. Windows 운영 체제에서 URB는 URB 구조에 설명되어 있습니다.
Microsoft는 USB 클라이언트 드라이버에 대한 루틴 라이브러리를 제공합니다. 이러한 루틴을 사용하여 USB 클라이언트 드라이버는 지정된 특정 작업에 대한 URB 요청을 빌드하고 USB 스택 아래로 전달할 수 있습니다. 원하는 경우 사용자 고유의 URB 요청을 빌드하는 대신 지원되는 작업에 대한 라이브러리 루틴을 호출하도록 클라이언트 드라이버를 디자인할 수 있습니다.
Windows 7 및 이전 버전의 URB 할당
Windows 7 및 이전 버전의 Windows용 WDK(Windows 드라이버 키트)에 포함된 루틴을 사용하여 USB 요청을 보내기 위해 클라이언트 드라이버는 일반적으로 URB 구조를 할당하고 채우고 URB 구조를 새 IRP와 연결하고 IRP를 USB 드라이버 스택에 보냅니다.
특정 유형의 요청에 대해 Microsoft는 URB 구조를 할당하고 형식을 지정하는 도우미 루틴(Usbd.sys 내보내기)을 제공합니다. 예를 들어 USBD_CreateConfigurationRequestEx 루틴은 URB 구조에 대한 메모리를 할당하고, select-configuration 요청에 대한 URB 형식을 지정하고, URB 구조체의 주소를 클라이언트 드라이버에 반환합니다. 그러나 도우미 루틴은 모든 유형의 요청에 사용할 수 없습니다.
Microsoft는 일부 유형의 요청에 대한 URL 형식을 지정하는 매크로도 제공합니다. 이러한 매크로의 경우 클라이언트 드라이버는 ExAllocatePoolWithTag를 호출하여 URB 구조를 할당하거나 스택에 구조를 할당해야 합니다. 예를 들어 클라이언트 드라이버가 URB를 할당한 후 드라이버는 UsbBuildSelectConfigurationRequest를 호출하여 선택 구성 요청에 대한 URB 형식을 지정하거나 구성을 지울 수 있습니다.
다른 요청의 경우 클라이언트 드라이버는 요청 유형에 따라 URB 구조의 다양한 멤버를 설정하여 URB 를 수동으로 할당하고 형식을 지정해야 합니다.
USB 요청이 완료되면 클라이언트 드라이버는 URB 구조를 해제해야 합니다. URB가 스택에 할당되면 범위를 벗어나면 URB가 해제됩니다. URB가 페이징되지 않은 풀에 할당된 경우 클라이언트 드라이버는 ExFreePool을 호출하여 URB를 해제해야 합니다.
Windows 8의 URB 할당
Windows 8용 WDK는 URL 할당, 서식 지정 및 해제를 위한 루틴을 내보내는 새 정적 라이브러리인 Usbdex.lib를 제공합니다. 또한 URB를 IRP와 연결하는 새로운 방법이 있습니다. Windows Vista 이상 버전의 Windows를 대상으로 하는 클라이언트 드라이버에서 새 루틴을 호출할 수 있습니다.
Windows Vista 이상에서 실행되는 클라이언트 드라이버는 기본 USB 드라이버 스택이 특정 성능 및 안정성 향상을 활용할 수 있도록 새 루틴을 사용해야 합니다. 이러한 개선 사항은 USB 3.0 디바이스 및 호스트 컨트롤러를 지원하기 위해 Windows 8에 도입된 새로운 USB 드라이버 스택에 적용됩니다. USB 2.0 호스트 컨트롤러의 경우 Windows는 향상된 기능이 지원되지 않는 이전 버전의 드라이버 스택을 로드합니다. 기본 드라이버 스택의 버전이나 호스트 컨트롤러에서 지원하는 프로토콜 버전에 관계없이 항상 새 URB 루틴을 호출해야 합니다.
새 루틴을 호출하기 전에 USB 드라이버 스택에 클라이언트 드라이버 등록을 위한 USBD 핸들이 있는지 확인합니다. USBD 핸들을 가져오려면 USBD_CreateHandle 호출합니다.
Windows 8용 WDK에서 사용할 수 있는 루틴은 다음과 같습니다. 이러한 루틴은 Usbdlib.h에 정의되어 있습니다.
- USBD_UrbAllocate
- USBD_IsochUrbAllocate
- USBD_SelectConfigUrbAllocateAndBuild
- USBD_SelectInterfaceUrbAllocateAndBuild
- USBD_UrbFree
- USBD_AssignUrbToIoStackLocation
이전 목록의 할당 루틴은 USB 드라이버 스택에 의해 할당되는 새 URB 구조에 대한 포인터를 반환합니다. Windows 에서 로드한 USB 드라이버 스택의 버전에 따라 URB 구조체를 불투명 URB 컨텍스트와 페어링할 수 있습니다. URB 컨텍스트는 URB에 대한 정보 블록입니다. URB 헤더의 내용을 볼 수 없습니다. 정보는 URB 추적 및 처리를 개선하기 위해 USB 드라이버 스택에서 내부적으로 사용하기 위한 것입니다. URB 컨텍스트는 Windows 8용 USB 드라이버 스택에서만 사용됩니다. URB 컨텍스트를 사용할 수 있는 경우 USB 드라이버 스택을 사용하여 URB 처리를 보다 안전하고 효율적으로 만듭니다. 예를 들어 USB 드라이버 스택은 클라이언트 드라이버가 URB를 제출하지 않았는지 확인한 다음 첫 번째 요청이 완료되기 전에 동일한 URB를 다시 사용하려고 시도해야 합니다. 이러한 종류의 오류를 감지하기 위해 USB 드라이버 스택은 URB 컨텍스트에 상태 정보를 저장합니다. 상태 정보가 없으면 USB 드라이버 스택은 들어오는 URB를 현재 진행 중인 모든 URL과 비교해야 합니다. 상태 정보는 클라이언트 드라이버가 URB를 해제하려고 할 때 USB 드라이버 스택에서도 사용됩니다. URB를 해제하기 전에 USB 드라이버 스택은 상태를 확인하여 URB가 보류 중이 아닌지 확인합니다.
URB 컨텍스트는 추가 URB 정보를 저장하기 위한 공식 메커니즘을 제공합니다. URB 컨텍스트를 사용하는 것이 필요에 따라 추가 메모리를 할당하거나 URB 구조의 예약된 멤버에 추가 정보를 저장하는 것이 좋습니다. USB 드라이버 스택은 URL 및 연결된 URB 컨텍스트를 페이징되지 않은 풀에 할당하므로 나중에 더 큰 URB 컨텍스트가 필요한 경우 풀 할당의 크기만 조정해야 합니다.
URB 루틴 마이그레이션
다음 표에는 URB 루틴의 변경 내용이 요약되어 있습니다.
사용 사례 | Windows 7 이하용 WDK에서 사용 가능 | Windows 8 이상용 WDK에서 사용 가능 |
---|---|---|
Windows 7 및 이전 버전의 운영 체제를 대상으로 합니다. | Windows 8 이상 버전의 운영 체제를 대상으로 합니다. | |
URB를 만들려면... | 클라이언트 드라이버는 URB 구조를 할당하고 요청에 따라 구조체의 형식을 지정합니다. 클라이언트 드라이버는 스택에 URB 구조를 할당하거나, 드라이버는 ExAllocatePoolWithTag를 호출하여 페이지가 지정되지 않은 풀의 구조를 할당합니다. |
클라이언트 드라이버는 USBD_UrbAllocate 호출하고 USB 드라이버 스택에 의해 할당되는 새 URB 구조에 대한 포인터를 받습니다. URB는 기본 USB 드라이버 스택의 USBD 인터페이스 버전에 따라 URB 컨텍스트와 연결될 수 있습니다. |
선택 구성 요청에 대한 URB를 만들려면... | 클라이언트 드라이버는 USB 드라이버 스택에서 만들고 포맷한 새 URB에 대한 포인터를 반환하는 USBD_CreateConfigurationRequestEx 루틴을 호출합니다. | 클라이언트 드라이버는 USBD_SelectConfigUrbAllocateAndBuild 호출하고 USB 드라이버 스택에 의해 할당되고 형식이 지정된 새 URB 구조에 대한 포인터를 받습니다(선택 구성 요청에 대해). URB는 기본 USB 드라이버 스택의 USBD 인터페이스 버전에 따라 URB 컨텍스트와 연결될 수 있습니다. |
선택 인터페이스 요청에 대한 URB를 만들려면... | 클라이언트 드라이버는 URB 구조를 할당하고 _URB_SELECT_INTERFACE 구조를 사용하여 USB 디바이스에 대한 선택 인터페이스 명령의 형식을 정의합니다. | 클라이언트 드라이버는 USBD_SelectInterfaceUrbAllocateAndBuild 호출하고 USB 드라이버 스택에 의해 할당되고 형식이 지정된 새 URB 구조에 대한 포인터를 받습니다(선택 인터페이스 요청에 대해). URB는 기본 USB 드라이버 스택의 USBD 인터페이스 버전에 따라 URB 컨텍스트와 연결될 수 있습니다. |
URB를 IRP와 연결하려면... | 클라이언트 드라이버는 IoGetNextIrpStackLocation을 호출하여 다음 IRP 스택 위치에 대한 포인터를 가져옵니다. 그런 다음 클라이언트 드라이버는 스택 위치의 Parameters.Others.Argument1 멤버를 URB 구조체의 주소로 수동으로 설정합니다. | 클라이언트 드라이버는 IoGetNextIrpStackLocation을 호출하여 다음 IRP 스택 위치에 대한 포인터를 가져옵니다. 그런 다음 클라이언트 드라이버는 USBD_AssignUrbToIoStackLocation 호출하여 URB를 스택 위치와 연결합니다. |
URB를 릴리스하려면... | 클라이언트 드라이버가 스택에 URB를 할당하는 경우 요청이 완료된 후 변수가 범위를 벗어집니다. 클라이언트 드라이버 또는 USB 드라이버 스택이 페이징이 아닌 풀에 할당된 URB 구조를 해제하기 위해 클라이언트 드라이버는 ExFreePool을 호출 합니다. |
클라이언트 드라이버가 USBD_UrbFree 호출합니다. |