How to Query the BSP Version Without Using Libraries

Is there an example program to query the running BSP version, without using the Toradex libraries?

You can use the following code to query the BSP version:

#include "windows.h"

// BSP Version Structure (old style)
typedef struct {
    DWORD ID;
    DWORD Maj;
    DWORD Min;
} BSPVER;

// BSP Version structure
typedef struct {
    WORD  BspId;
    WORD  FormId;
    DWORD Maj;
    WORD  Min;
    WORD  Beta;
    DWORD LoaderMaj;
    WORD  LoaderMin;
    WORD  LoaderBeta;
} BSPVEREX;

// IOCTL related definitions
#define FILE_DEVICE_HAL             0x00000101
#define METHOD_BUFFERED             0
#define FILE_ANY_ACCESS             0
#define CTL_CODE( DeviceType, Function, Method, Access ) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define IOCTL_HAL_GET_BSP_VER           (DWORD)(CTL_CODE(FILE_DEVICE_HAL,  2051,   METHOD_BUFFERED, FILE_ANY_ACCESS))

// function prototype to execute the IOCTL
BOOL KernelIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);

//=============================================================================
int _tmain(int argc, _TCHAR* argv[])
{
    BSPVEREX bspVer = {0};

    if(!KernelIoControl(IOCTL_HAL_GET_BSP_VER, NULL, 0, &bspVer, sizeof(BSPVEREX), NULL))
    {   // Try with the old size
        KernelIoControl(IOCTL_HAL_GET_BSP_VER, NULL, 0, &bspVer, sizeof(BSPVER), NULL); 
    }
}

The call using BSPVER works on all BSPs, the call using BSPVEREX only is supported on newer BSPs.

Some of the definitions are used for all IOCTL calls and are taken from general help files. However, I included the definitions here to avoid dependencies from other header files.

how to solve the link error:

error LNK2019: unresolved external symbol "int __cdecl KernelIoControl(unsigned long,void *,unsigned long,void *,unsigned long,unsigned long *)" (?KernelIoControl@@YAHKPAXK0KPAK@Z) referenced in function wmain

change

BOOL KernelIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);

to

extern "C" BOOL KernelIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);

You can read why here → What is the effect of extern "C" in C++? - Stack Overflow