다음을 통해 공유


샘플 코드에서 프로덕션 드라이버로 - 샘플에서 변경해야 할 사항

이 항목에서는 샘플 코드를 기반으로 디바이스 드라이버를 릴리스하기 전에 WDK 샘플 드라이버에 대해 수행해야 하는 중요한 변경 사항에 대해 설명합니다.

여기에 설명된 변경 내용 외에도 모든 드라이버는 신뢰할 수 있는 커널 모드 드라이버 만들기 및 Surface 팀 드라이버 개발 모범 사례에 설명된 모범 사례를 사용해야 합니다. 또한 모든 드라이버는 드라이버 보안 지침제공된 지침을 준수해야 합니다.

WDK 드라이버 샘플 - 고유 식별자

WDK(Windows 드라이버 키트)에는 드라이버 개발에 유용한 기술을 보여 주는 다양한 샘플 드라이버가 포함되어 있습니다. 이러한 샘플을 사용자 고유의 드라이버에 대한 기초로 사용할 수 있지만 드라이버를 릴리스하기 전에 사용자 고유의 디바이스 및 드라이버에 고유하게 적용하려면 명백한 운영 코드를 넘어 샘플의 특정 디바이스별 측면을 변경해야 합니다. 드라이버 작성기는 때때로 이러한 세부 사항을 간과합니다.

변경해야 하는 정확한 항목은 샘플마다 다르지만 일반적으로 특정 디바이스, 인터페이스 또는 드라이버를 식별합니다. 예를 들어 샘플 드라이버에 다음 항목이 포함된 경우 드라이버 및 디바이스에 적용하도록 변경해야 합니다.

  • GUID(Globally Unique Identifiers)

  • 기호화된 링크 이름

  • 디바이스 개체 이름

  • 풀 태그

  • I/O 제어 코드(IOCTL) 정의

  • 시스템 폴더에 복사되는 파일의 이름

  • 플러그 앤 플레이 디바이스 ID, 하드웨어 ID 및 호환 ID

  • 드라이버 서비스 이름

  • 디바이스 설명

  • 리소스 파일

이러한 변경을 잊어버리면 설치에 실패하고, 시스템의 다른 장치 및 드라이버와 충돌하며, 디버깅에 어려움을 겪을 수 있으며, 다른 오류도 발생할 수 있습니다.

예를 들어 "샘플" 이름을 샘플 드라이버의 고유한 이름으로 변경해야 한다는 오류가 ...\toastDrv\kmdf\toastmon\wdftoastmon.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. 표시될 수 있습니다.

GUIDs

드라이버는 GUID를 사용하여 디바이스 설정 클래스, 디바이스 인터페이스 클래스, 사용자 지정 PnP 이벤트, 사용자 지정 WMI(Windows Management Instrumentation) 이벤트 및 WPP(Windows PreProcessor) 추적 공급자를 식별합니다. 일부 GUID는 Microsoft에서 정의하고 다른 GUID는 디바이스 및 드라이버 공급업체에서 정의합니다.

일반 디바이스 및 WMI 데이터에 대한 디바이스 설정 클래스 GUID, 디바이스 인터페이스 클래스 GUID 및 WMI GUID는 모든 드라이버에서 사용할 WDK 또는 공용 헤더 파일에 정의됩니다. 이러한 GUID를 변경해서는 안 됩니다.

예를 들어 마우스를 구현하는 경우 WDK Ntddmou.h 헤더 파일에 정의된 GUID_DEVINTERFACE_MOUSE 디바이스 인터페이스 클래스로 계속 사용합니다. 그러나 새 디바이스 설정 클래스를 정의하는 경우 새 디바이스 설정 클래스 GUID 및 설정 클래스 이름과 새 디바이스 인터페이스 클래스 GUID도 생성해야 합니다. 설치 클래스 GUID 및 디바이스 인터페이스 클래스 GUID는 고유 값이어야 합니다. GUID를 공유할 수 없습니다.

대부분의 샘플 기반 드라이버의 경우 샘플의 로컬 헤더 또는 원본 파일에 정의된 GUID만 변경해야 하므로 샘플과 관련이 있습니다. 이러한 GUID에는 다음이 포함될 수 있습니다.

  • 사용자 지정 PnP 이벤트

  • 사용자 지정 WMI 이벤트

  • 새 디바이스 또는 사용자 지정 디바이스에 대한 디바이스 인터페이스 클래스

  • WPP 추적 공급자

다른 드라이버에 대해 정의된 GUID를 사용하면 두 드라이버가 동일한 시스템에 로드되는 경우 충돌이 발생할 수 있습니다. 예를 들어 두 드라이버가 동일한 GUID를 사용하여 디바이스 인터페이스를 등록하는 경우 디바이스 인터페이스를 열려는 클라이언트가 실수로 잘못된 디바이스를 열 수 있습니다.

다음은 모든 Toaster 드라이버 샘플에 포함된 Driver.h 파일에서 발췌한 내용입니다. 토스터 디바이스에 대한 디바이스 인터페이스 GUID를 정의합니다.

DEFINE_GUID(GUID_TOASTER_INTERFACE_STANDARD, \
            0xe0b27630, 0x5434, 0x11d3, 0xb8, 0x90, 0x0, 0xc0, \
            0x4f, 0xad, 0x51, 0x71);
// {E0B27630-5434-11d3-B890-00C04FAD5171}

사용자 고유의 드라이버에서 이 파일을 사용하는 경우 샘플 GUID(위에 굵은 텍스트로 표시됨)를 사용자 고유의 디바이스에 대한 인터페이스 GUID로 바꿔야 합니다. GUID를 만들려면 Microsoft Visual Studio 또는 Guidgen.exe GUID 만들기 도구를 사용합니다. 둘 다 Microsoft SDK(Windows 소프트웨어 개발 키트)에 포함되어 있습니다. 그런 다음 예제와 같이 GUID를 드라이버 헤더 파일의 기호 상수와 연결할 수 있습니다.

드라이버의 WMI 이벤트에 대한 새 GUID를 만들어야 할 수도 있습니다. 토스터 드라이버 샘플은 토스터 디바이스 도착 알림에 대해 다음 GUID를 정의합니다.

DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT, \
             0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, \
             0x27, 0x25, 0xe2, 0x9c);
// {01CDAFF1-C901-45b4-B359-B5542725E29C}

드라이버에서 각 WMI 이벤트에 대한 새 GUID를 만들어야 합니다.

샘플 드라이버에서 WPP 소프트웨어 추적을 사용하는 경우 샘플을 기반으로 하는 모든 드라이버에 대해 새 추적 공급자 GUID를 생성합니다. 예를 들어 %WinDDK%\Src\Kmdf\Osrusbfx2\Final의 Osrusbfx2 샘플의 Trace.h 헤더 파일은 다음과 같이 컨트롤 GUID를 정의합니다.

#define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID( \
           OsrUsbFxTraceGuid,(d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
        WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
        WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
        WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
        WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
       )

사용자 고유의 드라이버에서 굵게 표시된 텍스트를 드라이버별 이름 및 사용자가 만든 GUID로 바꿉 있습니다.

샘플에서 기호화된 링크 이름을 정의하는 경우 샘플의 이름을 사용자 고유의 드라이버에 적용되는 이름으로 바꿉니다. 그러나 \DosDevices\COM1과 같이 잘 알려진 링크 이름은 변경하지 마세요. 일반적으로 링크 이름이 샘플 이름(예: \DosDevices\CancelSamp)과 매우 유사한 경우 변경해야 합니다.

디바이스 인터페이스는 본질적으로 기호화된 링크이므로 다른 드라이버와 동일한 기호 링크를 사용하면 잘못된 디바이스 인터페이스 GUID를 사용하는 것과 같은 효과가 있습니다.

%WinDDK\Src\Kmdf\Toaster\Filter의 KMDF 토스터 필터 드라이버는 Filter.h 헤더 파일에 다음과 같이 정의된 문자열을 사용하는 기호 링크 이름을 만듭니다.

#define SYMBOLIC_NAME_STRING     L"\\DosDevices\\ToasterFilter"

굵게 표시된 문자열을 변경하여 사용자 고유의 드라이버를 보다 정확하게 설명합니다.

디바이스 개체 이름

샘플에서 디바이스 개체의 이름을 만드는 경우 샘플 코드를 적용할 때 이름을 변경해야 합니다.

KMDF 토스터 필터 드라이버는 다음과 같이 Filter.h 헤더 파일에서 디바이스 개체의 이름을 지정합니다.

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

기호 링크 이름과 마찬가지로 드라이버를 설명하도록 문자열을 변경해야 합니다.

명명된 디바이스 개체는 보안 위험을 나타낼 수 있습니다. PDO(물리적 디바이스 개체)에는 이름이 있어야 하며, 대부분의 이름은 드라이버에서 명시적으로 할당하는 대신 시스템이 생성됩니다. 다른 디바이스 개체는 애플리케이션과 드라이버 간의 사이드밴드 통신에 사용되는 제어 디바이스 개체를 나타내는 경우에만 이름을 지정해야 합니다. KMDF(커널 모드 드라이버 프레임워크)와 WDM(Windows 드라이버 모델)을 모두 사용하면 Windows에서 이름을 생성할 수 있습니다. 이 방법을 사용하면 디바이스 개체의 이름이 고유하고 권한 없는 사용자가 액세스할 수 없습니다. 자세한 내용은 KMDF 드라이버에서 디바이스 네임스페이스 액세스 제어 및 디바이스 액세스 제어를 참조하세요.

풀 태그

풀 태그는 특정 메모리 할당을 식별하고 디버깅에 도움이 될 수 있는 1~4자 리터럴입니다.

많은 샘플 드라이버는 Toaster.h의 다음 줄과 같이 드라이버 헤더 파일에서 풀 태그를 정의합니다.

#define TOASTER_POOL_TAG (ULONG) 'saoT'

드라이버는 디버거가 역순으로 표시하기 때문에 태그를 뒤로 정의합니다. 따라서 이 태그는 디버거 출력에서 Toas표시됩니다. 샘플에서 정의하는 태그를 사용하는 대신 고유한 코드를 고유하게 식별하도록 문자열을 변경합니다.

Pooltag.txt 파일에는 커널 모드 구성 요소 및 Windows와 함께 제공되는 드라이버에서 사용하는 풀 태그가 나열됩니다. Pooltag.txt %winddk%\Tools\Other<i>platform\Poolmon의 WDK와 함께 설치됩니다. 여기서 플랫폼은 amd64, i386 또는 ia64입니다. 이 목록에 표시되는 태그는 사용하지 마세요.

IOCTL 정의

디바이스 및 드라이버에 적합한 이름, 디바이스 유형, 함수 코드, 전송 형식 및 액세스 유형을 사용하도록 샘플 정의 I/O 제어 코드를 변경합니다.

예를 들어 Osrusbfx2 샘플에는 IOCTL_OSRUSBFX2_READ_SWITCHES 대한 다음 정의가 포함되어 있습니다.

#define IOCTL_OSRUSBFX2_READ_SWITCHES   
                    CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
                             IOCTL_INDEX + 6, \
                             METHOD_BUFFERED, \
                             FILE_READ_ACCESS)

다른 디바이스에 대한 샘플 기반 드라이버는 이 정의를 수정해야 합니다.

파일 이름

INF 또는 INX에서 드라이버의 이름, 공급업체에서 제공한 공동 설치 관리자 및 설치 프로시저가 시스템 폴더에 복사하는 기타 파일을 변경합니다. 이러한 파일 이름은 일반적으로 INF의 [SourceDisksFiles][ClassInstall32] 섹션 및 CopyFiles 항목에 표시됩니다.

다음 예제는 %WinDDK%\src\kmdf\Toaster\Func\Featured에서 사용할 수 있는 KMDF 추천 토스터 샘플의 INX 파일입니다. 변경해야 하는 파일 이름은 굵게 표시됩니다.

[ClassInstall32]
Addreg=ToasterClassReg
CopyFiles=ToasterClassInstallerCopyFileshighlight

[ToasterClassReg]
...
HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
...

[ToasterClassInstallerCopyFiles]
tostrcls.dll									    
...

파일의 이 부분을 다른 드라이버에 맞게 조정하려면 "tostrcls.dll"을 클래스 설치 관리자의 파일 이름으로 변경하고 "ToasterClassInstaller" 문자열을 변경하여 사용자 고유의 설치 관리자를 설명합니다. 이러한 변경은 설치 프로시저가 올바른 공동 설치 관리자 파일을 복사하고 레지스트리 키가 올바른 파일 이름을 기록하도록 합니다.

WDK 또는 Windows와 함께 제공된 공동 설치 관리자의 이름(예: KMDF, UMDF 및 WinUSB 공동 설치 관리자)은 변경하지 마세요.

이 예제와 같이 파일의 디바이스 설치 섹션 뒷부분에서 추가 변경이 필요합니다.

[Toaster_Device.NT]
CopyFiles=Toaster_Device.NT.Copy

[Toaster_Device.NT.Copy]
wdffeatured.sys

이 예제에서는 굵게 표시된 파일 이름을 생성된 드라이버 파일의 이름으로 변경합니다.

설치 프로그램에서 INF 및 드라이버 카탈로그 파일을 복사하면 이름이 바뀝니다. 따라서 드라이버 패키지에서 해당 이름을 반드시 변경할 필요는 없습니다. 그러나 일반적으로 INF 및 카탈로그 파일 이름이 드라이버 파일 이름과 유사한지 확인하는 것이 좋습니다.

PnP 디바이스 ID, 하드웨어 ID 및 호환 ID

설치 프로그램은 하드웨어 ID 및 호환 ID와 함께 디바이스 ID를 사용하여 디바이스 설치에 사용할 INF를 선택합니다.

디바이스 ID는 특정 디바이스를 고유하게 식별하는 공급업체 정의 문자열입니다. 모든 디바이스에는 정확히 하나의 디바이스 ID가 있습니다. 버스 드라이버는 열거 중에 디바이스 ID를 보고하고 설치 프로그램에서 이를 사용하여 디바이스를 올바른 INF 파일과 일치시킬 수 있습니다. 디바이스 ID는 INF의 [Manufacturer] 섹션에 정의되어 있습니다.

다음 예제에서는 Osrusbfx2.inx 파일에 지정된 OSR USB Fx2 디바이스의 디바이스 ID를 보여 줍니다.

[Manufacturer]
%MfgName%=Microsoft,NT$ARCH$

; For Win2K
[Microsoft]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002
...

; For XP and later
[Microsoft.NT$ARCH$]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002

사용자 고유의 드라이버에 대해 이 INF 지시문을 적용하려면 굵게 표시된 디바이스 ID를 자신의 디바이스에 대한 디바이스 ID로 바꿉니다. 또한 제조업체 이름을 회사 이름으로 변경해야 합니다.

하드웨어 ID 및 호환 ID는 디바이스 ID를 INF와 일치시킬 수 없는 경우 설치 프로그램에서 사용하는 덜 구체적인 ID입니다. INF에서 다른 디바이스를 지원할 수 있는 경우 디바이스 ID 외에 이러한 값을 변경해야 합니다. KMDF 추천 토스터 드라이버의 다음 예제는 하드웨어 ID를 보여줍니다.

[Manufacturer]
%StdMfg%=Standard,NT$ARCH$

; For Win2K
[Standard]
; DisplayName                   Section           DeviceId
; -----------                   -------           --------
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

; For XP and later
[Standard.NT$ARCH$]
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

사용자 고유의 드라이버에 대해 이 INF 지시문을 적용하려면 하드웨어 ID를 드라이버의 디바이스 ID로 바꾸고 "MsToaster"를 보다 설명적인 문자열로 변경합니다.

드라이버 서비스 이름

INF의 AddService 지시문에 있는 서비스 이름을 드라이버에 적합한 값으로 업데이트합니다. 드라이버 서비스 이름이 시스템의 다른 드라이버와 충돌하는 경우 드라이버는 설치하거나 로드하지 않습니다.

KMDF 추천 토스터 드라이버는 다음과 같이 서비스의 이름을 지정합니다.

[Toaster_Device.NT.Services]
AddService = wdffeatured, %SPSVCINST_ASSOCSERVICE%,
     wdffeatured_Service_Inst
      

서비스 이름은 AddService 지시문의 첫 번째 항목입니다 . 추천 토스터의 INF를 조정하려면 굵게 표시된 문자열을 드라이버에 더 적합한 문자열로 변경합니다. 이 예제에서 wdffeatured_Service_Inst 항목은 INF 정의 섹션만 참조하므로 변경은 중요하지 않습니다.

디바이스 설명

디바이스 설명은 일반적으로 INF의 [Strings] 섹션에서 정의되고 INF 전체의 다양한 위치에서 사용되는 여러 문자열로 구성됩니다. 예를 들어 KMDF 추천 토스터 샘플은 WdfFeatured.inx 파일에서 다음 문자열을 정의합니다.

[Strings]
SPSVCINST_ASSOCSERVICE   = 0x00000002
MSFT                     = "Microsoft"
StdMfg                   = "(Standard system devices)"
ClassName                = "Toaster"
DiskId1                  = "Toaster Device Installation Disk #1"
ToasterDevice.DeviceDesc = "Microsoft WDF Featured Toaster"
Toaster.SVCDESC          = "Microsoft WDF Toaster Featured Device Driver"

사용자 고유의 드라이버를 설치하도록 이 파일을 수정하려면 회사, 디바이스 및 드라이버에 대한 정보를 반영하도록 굵게 표시된 문자열을 변경해야 합니다.

INF의 [Manufacturer] 섹션에도 회사 이름이 표시되는 경우 해당 이름을 변경해야 합니다.

리소스 파일

드라이버 및 샘플별 공동 설치 관리자와 같은 다른 구성 요소에는 제품 이름, 파일 버전 및 회사 이름을 포함하여 드라이버별 문자열을 정의하는 리소스(.rc) 파일도 있습니다. 이러한 문자열을 드라이버 패키지에 적절한 값으로 변경합니다.

요약 - 어떻게 해야 하나요?

WDK 샘플을 기반으로 하는 드라이버를 릴리스하기 전에 원본 파일, INF 및 사용자 고유의 드라이버를 만드는 데 사용한 다른 리소스의 샘플 관련 정보를 바꿉니다. 필요한 변경 내용은 샘플마다 다르지만 일반적으로 샘플 드라이버 또는 해당 디바이스를 고유하게 식별하는 모든 정보를 포함합니다. 다음은 변경해야 하는 일반적인 내용입니다.

  • 적절한 경우 드라이버와 관련된 GUID를 생성하고 사용합니다.

  • 기호화된 링크 이름을 업데이트합니다.

  • 디바이스 개체의 이름을 업데이트하거나 자동 생성된 이름을 사용합니다.

  • 드라이버를 식별하고 알려진 태그와 충돌하지 않는 풀 태그를 사용합니다.

  • 드라이버 및 디바이스에 적합한 IOCTL 코드를 정의합니다.

  • 시스템 폴더에 복사된 파일의 이름을 업데이트합니다.

  • INF에 올바른 플러그 앤 플레이 디바이스 ID, 하드웨어 ID 및 호환 ID를 삽입합니다.

  • INF에서 드라이버의 서비스 이름을 업데이트합니다.

  • 디바이스 설명을 변경합니다.

  • 리소스 파일에서 드라이버별 문자열을 수정합니다.

  • 보안 및 안정성에 대한 모범 사례 준수

추가 정보

페니 오윅과 가이 스미스에 의해 Windows 드라이버 재단과 드라이버 개발

WDK 항목

새 GUID 정의 및 내보내기

KMDF 드라이버에서 디바이스 액세스 제어

드라이버 개발, 테스트 및 배포

신뢰할 수 있는 커널 모드 드라이버 만들기

Surface 팀 드라이버 개발 모범 사례

드라이버 보안 지침

첫 번째 드라이버 작성