드라이버 경고에 대한 코드 분석
이 섹션에서는 드라이버 코드에서 가능한 오류를 감지할 때 드라이버용 코드 분석에서 보고하는 경고를 나열하고 설명합니다. 일부 경고는 커널 모드 코드를 위한 것이며 사용자 모드 드라이버를 분석할 때 무시될 수 있습니다.
Important
드라이버에 대한 코드 분석은 Windows 24H2 WDK 및 EWDK에서 사용할 수 있지만 나중에 사용 중지되도록 설정되어 있는 것이 좋습니다.
앞으로 CodeQL은 드라이버의 기본 정적 분석 도구가 될 것입니다. CodeQL은 코드를 쿼리할 데이터베이스로 처리하는 강력한 쿼리 언어를 제공하므로 특정 동작, 패턴 등에 대한 쿼리를 간단하게 작성할 수 있습니다.
CodeQL 사용에 대한 자세한 내용은 CodeQL 및 정적 도구 로고 테스트를 참조하세요.
드라이버에 대한 코드 분석은 다음과 같은 유형의 경고를 보고합니다.
일반 경고 (6000-6999): C 및 C++ 구문의 잠재적 오류 및 일반적인 코딩 사례입니다. 이러한 경고에 대한 설명은 C/C++ 경고에 대한 코드 분석을 참조 하세요.
Windows 관련 경고 (28600-28799): 이러한 경고는 Windows의 특정 사용 패턴과 관련이 있지만 드라이버와는 관련이 없습니다.
드라이버 관련 경고 (28100-28199): 드라이버가 애플리케이션, 다른 드라이버 및 운영 체제와 상호 작용하는 동안 발생하는 오류입니다.
주석 오류 (28200-28299 및 36000-36999): 이러한 경고는 주석이 잘못된 컨텍스트에서 잘못 코딩되거나 사용되었음을 나타냅니다. 대부분의 경우 이러한 경고가 있으면 주석에 원하는(또는 임의의) 효과가 없음을 나타냅니다.
메모리 할당 경고 (30029-30035): 메모리 할당 경고입니다.
이 섹션의 내용
항목 | 설명 |
---|---|
경고 C28101: 드라이버 모듈에서 현재 함수가 올바른 함수 형식이 아니라고 유추했습니다. |
|
경고 C28110: 드라이버는 부동 소수점 하드웨어 상태를 보호해야 합니다. float 사용 참조 |
|
경고 C28111: 부동 소수점 상태가 저장된 IRQL이 현재 IRQL과 일치하지 않습니다(이 복원 작업의 경우). |
|
경고: C28114: 전체 IRP 스택 항목을 복사하면 지우거나 업데이트해야 하는 특정 필드가 초기화됩니다. |
|
경고 C28120: 함수는 현재 IRQ 수준에서 호출할 수 없습니다. 현재 수준이 너무 낮습니다. |
|
경고 C28121: 함수는 현재 IRQ 수준에서 호출할 수 없습니다. 현재 수준이 너무 높습니다. |
|
경고 C28122: 낮은 IRQ 수준에서 함수를 호출할 수 없습니다. 이전 함수 호출은 이 제약 조건과 일치하지 않습니다. |
|
경고 C28123: 함수는 높은 IRQ 수준에서 호출할 수 없습니다. 이전 함수 호출은 이 제약 조건과 일치하지 않습니다. |
|
경고 C28124: IRQ 수준이 분석 중인 함수에 허용되는 최소값 이하로 설정되도록 하는 호출입니다. |
|
경고 C28126: ObReferenceObject*에 대한 AccessMode 매개 변수는 IRP-RequestorMode>여야 합니다. |
|
경고 C28127: 루틴으로 사용되는 함수가 예상한 형식과 정확히 일치하지 않습니다. |
|
경고 C28128: 필드에 대한 액세스가 직접 수행되었습니다. 그것은 루틴에 의해 만들어져야한다. |
|
경고 C28129: 피연산자를 할당했습니다. 이 작업은 비트 집합 및 지우기를 사용하여 수정해야 합니다. |
|
경고 C28131: I/O 관리자가 버퍼를 해제하므로 DriverEntry 루틴은 포인터가 아닌 인수의 복사본을 저장해야 합니다. |
|
경고 C28132: 포인터 크기 가져오기 |
|
경고 C28133: IoInitializeTimer는 AddDevice에서 가장 잘 호출됩니다. |
|
경고 C28134: 풀 태그의 형식은 문자열 또는 문자열 포인터가 아니라 정수여야 합니다. |
|
경고 C28135: KeWaitForSingleObject에 대한 첫 번째 인수가 지역 변수인 경우 Mode 매개 변수는 KernelMode여야 합니다. |
|
경고 C28139: 인수가 형식과 정확히 일치해야 합니다. |
|
경고 C28141: 인수로 인해 IRQ 수준이 현재 IRQL 아래에 설정되고 이 함수는 해당 용도로 사용할 수 없습니다. |
|
경고 C28143: IoMarkIrpPending을 호출하는 디스패치 루틴도 STATUS_PENDING |
|
경고 C28144: 취소 루틴 내에서 종료 지점에서 Irp-CancelIrql>의 IRQL은 현재 IRQL이어야 합니다. |
|
경고 C28145: 드라이버에서 불투명 MDL 구조를 수정해서는 안 됩니다. |
|
경고 C28146: 커널 모드 드라이버는 strsafe.h가 아닌 ntstrsafe.h를 사용해야 합니다. 원본 파일에서 찾습니다. |
|
경고 C28147: 이 함수에 대한 호출에 기본 풀 태그('kdD' 또는 'mdW')를 사용하면 풀 태그 지정의 목적이 무효화됩니다. |
|
경고 C28150: 이 함수로 인해 IRQ 수준이 분석 중인 함수에 허용되는 최대값 이상으로 설정됩니다. |
|
경고 C28151: 값이 IRQL에 대한 법적 값이 아닙니다. |
|
경고 C28152: AddDevice와 유사한 함수의 반환이 예기치 않게 DO_DEVICE_INITIALIZING |
|
경고 C28153: 주석의 IRQL 값을 이 컨텍스트에서 평가할 수 없습니다. |
|
경고 C28156: 실제 IRQL이 필요한 IRQL과 일치하지 않습니다. |
|
경고 C28157: IRQL이 복원되지 않았습니다. |
|
경고 C28158: IRQL이 저장되지 않았습니다. |
|
경고 C28161: 부동 하드웨어를 사용할 권리를 획득하지 않고 종료 |
|
경고 C28162: 부동 소수점 하드웨어를 사용할 수 있는 권한을 보유하는 동안 종료 |
|
경고 C28165: 클래스의 함수 포인터가 함수 클래스와 일치하지 않습니다. |
|
경고 C28166: 함수는 IRQL을 현재 함수 항목에 있던 값으로 복원하지 않으므로 이 작업을 수행해야 합니다. |
|
경고 C28167: 함수는 IRQL을 변경하고 종료하기 전에 IRQL을 복원하지 않습니다. 변경 사항을 반영하도록 주석을 추가하거나 IRQL을 복원해야 합니다. |
|
경고 C28168: 디스패치 함수에 이 디스패치 테이블 항목과 일치하는 Dispatch_type 주석이 없습니다. |
|
경고 C28169: 디스패치 함수에 Dispatch_type 주석이 없습니다. |
|
경고 C28170: 함수가 페이징 세그먼트에 있다고 선언되었지만 PAGED_CODE PAGED_CODE_LOCKED 없습니다. |
|
경고 C28171: 함수에 PAGED_CODE 또는 PAGED_CODE_LOCKED 인스턴스가 두 개 이상 있습니다. |
|
경고 C28172: 함수에 PAGED_CODE 또는 PAGED_CODE_LOCKED 있지만 페이징 세그먼트에 있다고 선언되지 않았습니다. |
|
경고 C28173: 현재 함수가 4GB를 초과하는 실제 메모리에 잘못 적응하는 것처럼 보입니다. |
|
경고 C28175: 드라이버에서 구조체의 멤버에 액세스해서는 안 됩니다. |
|
경고 C28176: 드라이버에서 구조체의 멤버를 수정해서는 안 됩니다. |
|
경고 C28177: 함수는 둘 이상의 함수 클래스로 주석을 추가합니다. 하나를 제외한 모든 항목은 무시됩니다. |
|
경고 C28260: 함수 내의 속성을 구문 분석하는 동안 주석의 구문 오류가 발견되었습니다. |
|
함수의 속성에 대한 주석의 구문 오류가 발견되었습니다. |
|
경고 C28268: 함수의 함수 클래스가 여기에 사용된 typedef의 함수 클래스와 일치하지 않습니다. |
|
경고 C28601: HWND_BROADCAST 차단 방지 |
|
경고 C28602: HWND_BROADCAST 사용하여 SendMessageTimeout을 호출하지 않습니다. |
|
경고 C28604: 시간 제한이 0인 SMTO_ABORTIFHUNG SendMessageTimeout을 호출하지 않습니다. |
|
경고 C28615: __try 블록에서 _alloca 호출할 때 __except() 블록에서 _resetstkoflw 호출해야 합니다. catch() 블록 내부에서 _resetstkoflw 호출하지 마세요. |
|
경고 C28616: 다중 스레드 AV 조건 |
|
경고 C28617: _beginthread()의 반환 값을 사용하지 마세요. 대신 _beginthreadex() 사용 |
|
경고 C28623: GetMessagePos() 좌표의 서명되지 않은 캐스트입니다. LOWORD/HIWORD 대신 GET_X_LPARAM/GET_Y_LPARAM 사용 |
|
경고 C28624: LResultFromObject에서 증가된 refcount와 일치하도록 Release()에 대한 호출이 없습니다. |
|
경고 C28625: 중요한 데이터를 지우는 데 사용되는 함수 호출이 최적화됩니다. |
|
경고 C28636: GetSecurityDescriptorOwner/Group/Dacl/Sacl 호출에서 가져온 할당되지 않은 포인터에서 LocalFree 호출 |
|
경고 C28637: 전역 이니셜라이저에서 함수를 호출하는 것은 안전하지 않습니다. |
|
경고 C28638: 함수 지연 로드 스텁에 일치하는 선언이 없습니다. |
|
경고 C28639: 문자열을 사용하여 닫기 핸들 호출 |
|
경고 C28640: 함수 지연 로드 스텁은 정적 함수여야 합니다. |
|
경고 C28644: DPA_InsertPtr 반환 값이 선택되지 않음 |
|
경고 C28645: MessageBox가 더 이상 권장되지 않는 물음표 메시지 기호를 사용하여 호출되었습니다. |
|
경고 C28648: PulseEvent는 신뢰할 수 없는 함수입니다. |
|
경고 C28649: 자동 또는 전역 스택 배열은 NULL이 되지 않습니다. |
|
경고 C28650: !0이 사용되는 형식이 오류 사례로 처리되지 않습니다. 상태 값(예: ! )을 반환합니다. TRUE는 실패를 나타내는 상태 값을 반환하는 것과 동일하지 않습니다. |
|
경고 C28651: 정적 이니셜라이저로 인해 멤버 함수 포인터로 인해 쓰기 페이지에 복사가 발생합니다. |
|
경고 C28652: 정적 이니셜라이저는 오버로드된 비트 연산자로 인해 쓰기 페이지에서 복사를 발생합니다. |
|
경고 C28714: 의미상 다른 정수 형식 간에 캐스팅 |
|
경고 C28715: 의미상 다른 정수 형식 간에 캐스팅 |
|
경고 C28716: 의미상 다른 정수 형식 간에 컴파일러 삽입 캐스트 |
|
경고 C28717: VARIANT 형식이 잘못되었습니다. |
|
경고 C28718: 주석이 지정되지 않은 버퍼 |
|
경고 C28719: 금지된 API 사용 |
|
경고 C28720: 금지된 API 사용 |
|
경고 C28721: 사용되지 않는 성능 카운터 아키텍처 |
|
경고 C28722: 함수 선언에서 주석이 지정되지 않은 버퍼 |
|
경고 C28723: 함수 정의에 해당 선언이 없는 주석이 없는 버퍼 |
|
경고 C28725: 이 SetUnhandledExceptionFilter 대신 Watson 사용 |
|
경고 C28726: 금지된 API 사용 |
|
경고 C28727: 금지된 API 사용 |
|
경고 C28728: 금지된 API 사용 |
|
경고 C28730: 포인터에 직접 '\0'을 할당할 수 있습니다. |
|
경고 C28735: 금지된 진홍색 API 사용 |
|
경고 C28736: 금지된 API 인수 사용 |
|
경고 C28740: 주석이 지정되지 않은 부호 없는 버퍼 |
|
경고 C28741: 함수에서 주석이 지정되지 않은 버퍼 |
|
경고 C28742: 함수에서 주석이 지정되지 않은 버퍼 |
|
경고 C28750: lstrlen 및 해당 변형의 사용 금지 |
|
경고 C28751: ExAllocatePool 및 해당 변형의 사용 금지 |
|
경고 C28752: kernel32 또는 advapi32 API의 사용 금지 |
|
경고 C28753: 매개 변수 평가의 정의되지 않은 순서에 의존 |
|
경고 C30029: 실행 가능한 메모리를 요청하는 메모리 할당 함수 호출 |
|
경고 C30030: 메모리 할당 함수를 호출하고 실행 가능한 메모리를 나타내는 매개 변수 전달 |
|
경고 C30031: 메모리 할당 함수를 호출하고 실행 가능한 메모리를 나타내는 매개 변수 전달 |
|
경고 C30032: 메모리 할당 함수를 호출하고 POOL_NX_OPTOUT 지시문을 사용하여 실행 메모리 요청을 강제합니다. |
|
경고 C30033: POOL_NX_OPTIN 사용하여 컴파일된 드라이버에서 실행 파일 할당이 검색되었습니다. 이 드라이버는 런타임에 다른 드라이버에 의해 로드되도록 결정되었습니다. 로드 드라이버가 DriverEntry에서 ExInitializeDriverRuntime(DrvRtPoolNxOptIn)을 호출하는지 확인합니다. |
|
경고 C30034: 할당 함수에 플래그 값을 전달하면 실행 가능한 메모리가 할당될 수 있습니다. 할당 함수가 페이징되지 않은 실행 가능한 풀 형식을 요청하지 않는지 확인하세요. |
|
경고 C30035: 초기화 함수(예: DriverEntry() 또는 DllInitialize()) 내부에서 수행해야 하는 함수를 호출했습니다. PREfast가 초기화 함수에서 호출되었는지 여부를 확인할 수 없습니다. |