wdk7600 Sources file usage

source multi file programming

I. multiple documents

1.1 purpose introduction

People who write windows kernel drivers may now use advanced WDK For example, WDK is automatically integrated into VS
But I still like WDK 7600 because the compiled drivers are very compatible And you can use the path under vscode configuration
But WDK 7600 is more troublesome to write For example, how to program multiple files How to include libraries How to compile into a library
How to use C/C + + code to write So this blog or this post is also a record When a new problem is encountered, the addition will continue

1.2 known SOURCES fields

II. Main topic

2.1 separation of include file and CPP file

The first way is to separate the inclusion file from the cpp/c file

Directory A stores your XXX H file
Directory B (main directory) stores XXX H implementation file

Then, the sources in directory B should be changed as follows

TARGETNAME=testDriver1
TARGETPATH=.
TARGETTYPE=DRIVER

MSC_WARNING_LEVEL= /W3 /WX


INCLUDES= \
        ./test1             
        
SOURCES= Driver.cpp\
         test.cpp

INCLUDES indicates the path you include You can also use the path of the system
For example:

example:
INCLUDES=   $(INCLUDES) \
            $(DDK_INC_PATH); \
            ..\common; \
            ..\..\util;


INCLUDES = $(DDK_INC_PATH);\

DDK_INC_PATH == WDKROOT\inc\ddk

Directory B holds driver CPP and test CPP, and test. Is stored in directory A h

Driver.cpp is the main entrance Test. Is referenced in DriverEntry h

  • Test. In directory A H code
#ifdef __cplusplus
extern "C"
{
#endif

#include <ntifs.h>
#include <ntddk.h>
#include <Ntstrsafe.h>
#include "ntimage.h"
#ifdef __cplusplus
}
#endif


PVOID testprint();
  • Driver in directory B CPP and test Implementation of CPP
    Driver.cpp
#include <ntifs.h>
#include <ntddk.h>
#include "test.h"
VOID DriverUnLoad(
    PDRIVER_OBJECT DriverObject)
{
    KdPrint(("Exit"));
}

extern "C" NTSTATUS DriverEntry(
    PDRIVER_OBJECT pDriverObj,
    PUNICODE_STRING pReg)
{
    UNREFERENCED_PARAMETER(pDriverObj);
    UNREFERENCED_PARAMETER(pReg);
    KdBreakPoint();
    testprint();        //Referenced test Functions in H
    return STATUS_SUCCESS;
}

test.cpp

#include "test.h"

PVOID testprint()
{
    DbgPrint("testprint");
    return NULL;
}

If it is not added in sources

INCLUDES= \
        ./test1  

Then it will be reported that XXX cannot be found h
Of course, if it's in your home directory h.cpp are all in the same directory Then just specify what you want to compile cpp is enough

2.2 32-bit driver uses 32-bit inline assembly

Drivers can use inline assembly when compiling 32 - bit drivers

The contents of the sources file are as follows:

TARGETNAME=testDriver1
TARGETPATH=.
TARGETTYPE=DRIVER

DRIVERTYPE=FS

MSC_WARNING_LEVEL= /W3 /WX



i386_SOURCES=       \
    test386.cpp

SOURCES=Driver.cpp\

New field i386 used_ SOURCES
Because of our test cpp test. h Driver. CPP is in the same directory Therefore, there is no need to use the scheme of 2.1 to add inicloud path
Examples are as follows:

Driver.cpp

#include <ntifs.h>
#include <ntddk.h>
#include "test.h"
VOID DriverUnLoad(
    PDRIVER_OBJECT DriverObject)
{
    KdPrint(("Exit"));
}

extern "C" NTSTATUS DriverEntry(
    PDRIVER_OBJECT pDriverObj,
    PUNICODE_STRING pReg)
{
    UNREFERENCED_PARAMETER(pDriverObj);
    UNREFERENCED_PARAMETER(pReg);
    KdBreakPoint();
    test();
    return STATUS_SUCCESS;
}

test.h

#ifdef __cplusplus
extern "C"
{
#endif

#include <ntifs.h>
#include <ntddk.h>
#include <Ntstrsafe.h>
#include "ntimage.h"
#ifdef __cplusplus
}
#endif

PVOID test();

test.cpp

#include "test.h"
PVOID __declspec(naked) test()
{
    _asm {
        mov eax,eax 
        ret
    }
}

2.3 assembly under 64 bit

Reserved for solution

2.4 multi directory programming

If you have multiple driver projects that you want to compile together, the method is as follows
First, create a DIRS file The content of the file indicates the file directory of the driver you want to compile
But you should indicate the sources file in your directory Or the new DIRS
DIRS

DIRS= \
     A \
     B \
     C

The above meaning means to compile the driver under the three file directories a, B and C
If there are SOURCES in directory a, the SOURCES file will be read and compiled A table of contents If directory B has embedded folders and DIRS, DIRS will be read first and continue to search for embedded folders in directory B Compile until you find a directory where SOURCES exists

2.5 compilation level

If you want to make your driver compile more strictly The following fields can be defined in SOURCES

MSC_WARNING_LEVEL= /W3 /WX

/W3 is the warning level / W1 / W2 / W3 / W4 / W4 is the most stringent If the parameter is not used, it needs to be used
UNREFERENCED_PARAMETER(pDriverObj); To include
/WX should be warning or error

2.6 compiling into Library

We can compile our drivers into libraries This involves library development

namely:

  1. How to generate Library in driver
  2. How to use custom libraries in drivers

2.6.1 how to generate Library in driver

First of all, if you are developing in C/C + +, you should give one h and a cpp file
Assume test h test. CPP as an example
The contents of the driver's sources file should be as follows:

TARGETNAME=test
TARGETPATH=.
TARGETTYPE=LIBRARY
DRIVERTYPE=FS

MSC_WARNING_LEVEL= /W3 /WX


INCLUDES= \
        ./test

SOURCES= test.cpp

My directory structure is:

ROOTDIR
    test(DIR)
        test.h
test.cpp

test.h as follows:

#ifdef __cplusplus
extern "C"
{
#endif

#include <ntddk.h>

#ifdef __cplusplus
}
#endif


class test
{
private:
    /* data */
public:
    test(/* args */);
    ~test();
    PVOID testprint();
};

test.cpp

#include "test.h"

test::test(/* args */)
{
}

test::~test()
{
}

PVOID test::testprint()
{
    DbgPrint("testprint");
    return NULL;
}

After generation, a test. Is generated Lib Library

2.6.2 library used in driver

Using the library is simple Copy the header file
Then indicate it in SOURCE

The sources are as follows:

TARGETNAME=test1
TARGETPATH=.
TARGETTYPE=DRIVER


MSC_WARNING_LEVEL= /W3 /WX


INCLUDES= \
        ./test

TARGETLIBS = .\libs\test.lib
SOURCES= Driver.cpp

test.h same as above
Driver.cpp is as follows:

#include "test\test.h"

VOID DriverUnLoad(
    PDRIVER_OBJECT DriverObject)
{
    KdPrint(("Exit"));
}

extern "C" NTSTATUS DriverEntry(
    PDRIVER_OBJECT pDriverObj,
    PUNICODE_STRING pReg)
{
    UNREFERENCED_PARAMETER(pDriverObj);
    UNREFERENCED_PARAMETER(pReg);
    KdBreakPoint();
    pDriverObj->DriverUnload = DriverUnLoad;
    test t;
    t.testprint();
    return STATUS_SUCCESS;
}

If it is C language, it can be compiled directly

About TARGETLIBS, you can also include paths
For example:

 TARGETLIBS = $(DDK_LIB_PATH)\xxx1.lib\
              $(DDK_LIB_PATH)\xxx2.lib\
For example, include ntstrsafe.lib library
TARGETLIBS= $(DDK_LIB_PATH)\ntstrsafe.lib 

The paths provided by the system are as follows:

DDK_LIB_PATH  == WDKROOT\lib\Version\*
SDK_LIB_PATH  == WDKROOT\lib\Version\*
CRT_LIB_PATH 

2.7 definition of C constant

C can be used in the SOURCES file_ DEFINES
It means equivalent to you in the world c file uses #define to declare macros

TARGETNAME=test1
TARGETPATH=.
TARGETTYPE=DRIVER


MSC_WARNING_LEVEL= /W3 /WX

!IFDEF DDKBUILDENV
C_DEFINES=$(C_DEFINES) -DDDK_BUILD
!ENDIF

INCLUDES= \
        ./test

TARGETLIBS = .\libs\test.lib
SOURCES= Driver.cpp

Example 2:

C_DEFINES=$(C_DEFINES) /wd4996

2.8 SOURCES indicates the compiled files and condition macros

Found in WDK You can compile resources for the driver. You can define two sources to point to the file to be compiled
Then the final reference

example:

!if $(IA64)  
    xxxxx Conditional use IA64 
!endif

DIR_SOURCES=wacompen.c  \
            wacompen.rc \
            oempen.c    \
            errcodes.mc

STB_SOURCES=hid.c    \
            pnp.c       \
            serial.c    \
            errlog.c


SOURCES=    $(DIR_SOURCES) $(STB_SOURCES)

Added by aleksandra on Mon, 03 Jan 2022 12:05:33 +0200