Почему макрос NTDDI_VERSION меняет свое значение с включенного в него cpp на ntdddisk.h?

Почему макрос NTDDI_VERSION меняет свое значение с включенного в него cpp на ntdddisk.h?

Я использую Visual Studio 2012 с накопительным обновлением 4 и использую Windows 7 x64.

В одном CPP мне нужно вызвать новый IOCTL_.. для WIN 8.

В СРР есть #include

ntdddisk.h определяет новый IOCTL_ для WIN 8 в защищенном состоянии:

#if (NTDDI_VERSION >= NTDDI_WIN8)
...
#endif

Внутри этого cpp макрос NTDDI_VERSION имеет значение NTDDI_WIN8 (ожидаемый результат включения sdkddkver.h и компиляции с /D_WIN32_WINNT=0x0602)

Однако в ntdddisk.h значение для макроса NTDDI_VERSION имеет значение ‹ NTDDI_VISTA, то есть меньше, чем NTDDI_WIN8

Компиляция завершается с ошибкой

error C2065: 'IOCTL_..' : undeclared identifier

Похоже на ошибку, если я не пропущу что-то еще. Мысли?

Подробности:

В файле CPP есть эти включения

#pragma once
// Needed for  new IOCTL_  for  WIN 8 
#include <sdkddkver.h>
#include <windows.h>
// Check  NTDDI_VERSION ...
#if (NTDDI_VERSION >= NTDDI_WIN8)
// Value is  NTDDI_WIN8 as expected
// #include <TROUBLE.h>
#endif

#pragma pack(8)
#include <ntdddisk.h>
#include <ntddscsi.h>
#include <lm.h>
#include <objbase.h>

/*=== IMPORTANT: this struct needs to have 8-byte packing ===*/
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
    SCSI_PASS_THROUGH spt;
    ULONG             Filler;      // realign buffers to double word boundary
    UCHAR             SenseBuf[32];
    UCHAR             DataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFERS;
#pragma pack()

Компиляция с CL имеет эти параметры в том числе и с -D_WIN32_WINNT=0x0602

cl -nologo @COMPL.TMP /Fo..\\..\\..\\optimized\\obj\\x86\\CPP.obj CPP.cpp

COMPL.TMP содержит

/I*** application-headers ***       
-D_AFXDLL -c -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DBTREEDB -O2 -Ox -MD -Zi   -DNT_CLIENT -DWIN32 -D"_CONSOLE"  -D_THREADS  -D_OPSYS_TYPE=DS_WINNT  -DPSAPI_VERSION=1 -D_WIN32_WINNT=0x0602 -TP -DMBCS=1 -D_LONG_LONG=1 -D_DSM_VLK_BTREE -DDSM_WIDECHAR  -D_UNICODE -DUNICODE  -DUSE_XML=1 -DXMLUTIL_EXPORTS=1 -DUSE_XERCES_2_8=1 -DPEGASUS_PLATFORM_WIN32_IX86_MSVC=1 -DPEGASUS_USE_EXPERIMENTAL_INTERFACES -Zp1 -D_DSM_LONG_NAME    -W3 -EHsc -GF       

person TonyI    schedule 30.05.2014    source источник


Ответы (2)


Проблема не в макросах _WIN32_WINNT или NTDDI_VERSION.

Проблема в том, что windows.h косвенно включает winioctl.h, в котором примерно посередине есть пара любопытных строк:

#ifndef _NTDDDISK_H_
#define _NTDDDISK_H_

Неудивительно, что ntdddisk.h начинается с тех же самых строк и поэтому фактически вообще не включается.

Я не мог легко придумать комбинацию или порядок заголовков, которые помогли бы обойти эту проблему - я думаю, что это то, что MS действительно нужно исправить.

Однако следующий ужасный обходной путь (который я действительно не предлагаю, если вы не можете получить какую-либо помощь от MS), похоже, заставил компилятор фактически обработать ntdddisk.h:

#define _NTDDDISK_H_
#include <windows.h>
#undef _NTDDDISK_H_

Но я подозреваю, что в результате этого взлома могут возникнуть другие проблемы, поэтому, если вы решите его использовать, внимательно проверьте его.

person Michael Burr    schedule 30.05.2014

Я не уверен, что это то, что мне нужно, но компиляция заработала после вставки

 #define _NTDDDISK_H_
 #include <windows.h>
 ...
 #undef _NTDDDISK_H_
 #include <ntdddisk.h>

Спасибо за предложение.

person TonyI    schedule 30.05.2014