Coder Social home page Coder Social logo

windows-driver-frameworks's Introduction

Windows Driver Frameworks

The Windows Driver Frameworks (WDF) are a set of libraries that make it simple to write high-quality device drivers.

Goals for this project

Developers can use the MSDN reference documentation to learn about the core concepts of WDF and the APIs available for use. Still, there's no substitute for actual source code. That's why we've published the source behind KMDF and UMDF v2 for anyone to dig through and debug drivers with.

Learning from the source

Unsure about what a particular WDF method is doing? Take a look at the source. Our aim is to make the inner workings of WDF as transparent for developers as possible.

Note: As you experiment with WDF, you may come across undocumented behavior or APIS. We strongly advise against taking dependencies on that behavior as it's subject to change in future releases.

Debugging with the framework

Using the source in this repo, developers can perform step-through debugging into the WDF source. This makes it much easier to follow driver activity, understand interactions with the framework, and diagnose issues. Debugging can be done live by hooking onto a running driver or after a crash by analyzing the dump file. See the debugging page in the wiki for instructions.

Scope

With this initial release, we've published the source behind KMDF and UMDF v2. You'll find that a great deal of the source is shared between the two. Driving the frameworks forward with a unified model is a key priority for the WDF team.

Contributing to WDF

See CONTRIBUTING.md for policies on pull requests to this repo.

FAQ about this repo

See the FAQ page in the Wiki.

Licensing

WDF is licensed under the MIT License.

Related Repos

Driver samples for Windows 10 now also live on GitHub.

windows-driver-frameworks's People

Contributors

ajbarb avatar david1234321 avatar jmrossy avatar microsoft-github-policy-service[bot] avatar wm1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

windows-driver-frameworks's Issues

WdfDmaTransactionInitialize fails with STATUS_BUFFER_TOO_SMALL for TransactionLength = 4GB-4KB and DmaRemappingCompatible=1

if ((transferLength + PAGE_SIZE) < (Length + pageOffset )) {

To replicate, create a WDFDMAENABLER

#define COMMON_BUFFER_SIZE (4294967296-4096)

    WDF_DMA_ENABLER_CONFIG_INIT(&dma, WdfDmaProfileScatterGather64Duplex, COMMON_BUFFER_SIZE);
    dma.WdmDmaVersionOverride = 3;
    dma.Flags = WDF_DMA_ENABLER_CONFIG_NO_SGLIST_PREALLOCATION;
    status = WdfDmaEnablerCreate(device, &dma, WDF_NO_OBJECT_ATTRIBUTES, &context->Dma);

Use DmaRemappingCompatible as 1 in the .inf.
Create a DomainCommonBuffer:

    dma = WdfDmaEnablerWdmGetDmaAdapter(context->Dma, WdfDmaDirectionReadFromDevice);
    ops = dma->DmaOperations;
    domain = ops->GetDmaDomain(dma);
    type = MmCached;
    status = ops->AllocateDomainCommonBuffer(dma, domain, NULL, COMMON_BUFFER_SIZE,
                0, &type, MM_ANY_NODE_OK, &context->LA, &context->Ptr);
    RtlZeroMemory(context->Ptr, COMMON_BUFFER_SIZE);

Create a MDL, pass it to WdfDmaTransactionInitialize

    context->Mdl = IoAllocateMdl(NULL, COMMON_BUFFER_SIZE, FALSE, FALSE, NULL);
    MmInitializeMdl(context->Mdl, context->Ptr, COMMON_BUFFER_SIZE);
    MmBuildMdlForNonPagedPool(context->Mdl);
    status = WdfDmaTransactionInitialize(transaction, ScatterGatherEntry,
                    WdfDmaDirectionReadFromDevice, context->Mdl, context->Ptr,
                    COMMON_BUFFER_SIZE);

The runtime code is STATUS_BUFFER_TOO_SMALL. The expected result is STATUS_SUCCESS.

Using #define COMMON_BUFFER_SIZE (4294967296-8192) works.

The Markup for CONTRIBUTING.md is incorrect

In /CONTRIBUTING.md, there are three issues with the Markdown formatting:

  1. The highest-level heading in the file is a ##, which is a second-level heading; the second heading is a ###, which is a third-level heading.
  2. Markdown headings require a space between the # and the text of the heading.
  3. Markdown paragraphs require a blank line separating them.

For example:

# Heading 1

Content 1

## Heading 2

Content 2.1

Content 2.2

Renders as:

Heading 1

Content 1

Heading 2

Content 2.1

Content 2.2

Typos

There are several typos in the repository on the word "separate" which is transformed into "seperate":

Tasks

_IRQL_requires_max_ missing

_IRQL_requires_max_ is missing from a few methods. IRQL requirements for these functions are documented in the MSDN though.

WdfObjectAllocateContext should have _IRQL_requires_max_(DISPATCH_LEVEL) MSDN (and possibly _Must_inspect_result_)
WdfObjectReferenceActual should have _IRQL_requires_max_(DISPATCH_LEVEL) MSDN
WdfObjectDereferenceActual should have _IRQL_requires_max_(DISPATCH_LEVEL) MSDN

This list is non-exhaustive. If desired I can keep adding functions with missing declarations.

Licensing confusion

The README states that WDF is licensed under the MIT license. However, a large number of the files distributed with WDF contain the provision "All rights reserved", which may be easily taken to contradict the rights that the MIT license expressly grants. Can this please be clarified; i.e. are these files under a stricter license than the rest of the source, or is the entire source intended to be taken as under the MIT license?

Thanks,
Zebediah Figura

WdfMemoryCreate of size BufferSize < PAGE_SIZE && BufferSize > PAGE_SIZE - sizeof(FxMemoryBuffer) crosses page boundaries

Creating a buffer with WdfMemoryCreate of size 4092 (and probably any value between (PAGE_SIZE - 0x7f) and (PAGE_SIZE - 1)) will not create a buffer entirely resident in a single physical page, contradicting WdfMemoryCreate documentation.

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfmemory/nf-wdfmemory-wdfmemorycreate
The documentation states the following:
If BufferSize is less than PAGE_SIZE, the operating system gives the caller exactly the number of requested bytes of memory. The buffer is not necessarily page-aligned, but it is aligned by the number of bytes that the MEMORY_ALLOCATION_ALIGNMENT constant specifies in Ntdef.h. Buffers of PAGE_SIZE or less do not cross page boundaries.
If BufferSize is PAGE_SIZE or greater, the system allocates a page-aligned buffer. If the PoolType parameter is NonPagedPool, the system allocates the number of pages that are necessary to hold all of the bytes. Any unused bytes on the last-allocated page are essentially wasted.

The sentence issue in question is "Buffers of PAGE_SIZE or less do not cross page boundaries." When allocating a WDFMEMORY of size 4092, I found the buffer begins at offset 0x80 in one page, ending at 0x7c in the next page, and therefore crossing page boundaries. The first 0x80 bytes of the page seem to contain the WDFMEMORY object (type FxMemoryObject). This is important to us as the physical addresses may not necessarily be contiguous if the buffer crosses page boundaries.

Code which encounters this issue looks like so (variable names changed and other code omitted):

typedef struct ITEM {
char[44] data; // actual fields omitted.
} ITEM, *P_ITEM;

#define NUM_ITEMS ((UINT32)(PAGE_SIZE / sizeof(ITEM))) // As many full items as fit in a single page. Change to another, smaller value if desired.
STATIC_ASSERT(NUM_ITEMS * sizeof(ITEM) <= PAGE_SIZE); // Make sure NUM_ITEMS above is sane. Later code relies on items not spanning pages.

// Note: (NUM_ITEMS * sizeof(ITEM)) == 4092. sizeof(ITEM) == 44 and NUM_ITEMS == 93.
status = WdfMemoryCreate(&attributes,
                         NonPagedPoolNx,
                         MY_MEM_TAG,
                         NUM_ITEMS * sizeof(ITEM),
                         &Ctx->MemObj,
                         &Ctx->Buffer);
// Omitted: Error handling

physBaseAddr = MmGetPhysicalAddress(Ctx->Buffer);
// An individual item should not span pages. We'll double-check the whole buffer lies in a single
// physical page here.
NT_ASSERT(((physBaseAddr.QuadPart & (PAGE_SIZE-1)) + (NUM_ITEMS * sizeof(ITEM))) <= PAGE_SIZE);

Windbg output (shortened):
kd> dx -r1 ((driver!MY_CONTEXT *)0xffffcd0bd5202750)
...
[+0x0d0] MemObj : 0x32f429df7ff8 [Type: WDFMEMORY__ *]
[+0x0d8] Buffer : 0xffffcd0bd6208080 [Type: void *]

Note, the Buffer is offset from the page boundary by 0x80. Adding 4092 to that address will cross into the next page.

kd> !wdfkd.wdfhandle 0x32f429df7ff8
...
!wdfobject 0xffffcd0bd6208000

Note, the wdfobject address is Ctx->Buffer - 0x80.

kd> dt Wdf01000!FxMemoryObject 0xffffcd0bd6208000
...
+0x00a m_ObjectSize : 0x1080
...
+0x070 m_BufferSize : 0xffc

Creating a buffer of BufferSize == PAGE_SIZE does not result in the same issue:

kd> dx -r1 (*driver!MY_CONTEXT *)0xffffcd0bd484bae0))
...
[+0x0d0] MemObj : 0x32f42bd355a8 [Type: WDFMEMORY__ *]
[+0x0d8] Buffer : 0xffffcd0bd3823000 [Type: void *]

kd> dt Wdf01000!FxMemoryObject 0xffffcd0bd42caa50
...
+0x00a m_ObjectSize : 0x80
...
+0x070 m_BufferSize : 0x1000

Note, ObjectSize is 0x80 instead of 0x1080 and Buffer ends in 0x000 rather than 0x80.

In the source for FxMemoryObject, I see memory is created from pool (and is therefore page-aligned) rather than along with the Object in the following case:

78 if (BufferSize >= PAGE_SIZE ||
79 (FxDriverGlobals->FxVerifierOn && FxDriverGlobals->FxPoolTrackingOn) ||
80 FxIsPagedPoolType(PoolType)) {

I believe that 78 will need to be changed to something like:
78 if (BufferSize >= (PAGE_SIZE – sizeof(FxMemoryBuffer))

I would submit a patch myself, but I am not familiar with the process for building and testing the WDF framework, so I would rather leave that up to the maintainers.

WDF not source indexed in Windows 10 1511

No update to this repository has been committed for Windows 10 Build 10586. Furthermore, the PDB for Wdf01000.sys in the Microsoft Symbol Server is not source indexed:

0:000> lmv m wdf01000
Browse full module list
start             end                 module name
00000001`c0000000 00000001`c00c5000   Wdf01000   (private pdb symbols)  c:\websymbols\Wdf01000.pdb\BBFAAF05FB9E4C71900015FF4A30AA8C1\Wdf01000.pdb
    Loaded symbol image file: Wdf01000.sys
    Mapped memory image file: C:\Windows\System32\drivers\Wdf01000.sys
    Image path: C:\Windows\System32\drivers\Wdf01000.sys
    Image name: Wdf01000.sys
    Browse all global symbols  functions  data
    Timestamp:        Fri Oct 30 04:24:27 2015 (5632D4DB)
    CheckSum:         000CE0F2
    ImageSize:        000C5000
    File version:     1.17.10586.0
    Product version:  1.17.10586.0
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        3.7 Driver
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® Windows® Operating System
    InternalName:     wdf01000.sys
    OriginalFilename: wdf01000.sys
    ProductVersion:   1.17.10586.0
    FileVersion:      1.17.10586.0 (th2_release.151029-1700)
    FileDescription:  Kernel Mode Driver Framework Runtime
    LegalCopyright:   © Microsoft Corporation. All rights reserved.
0:000> !lmi wdf01000.sys
Loaded Module Info: [wdf01000.sys] 
         Module: Wdf01000
   Base Address: 00000001c0000000
     Image Name: Wdf01000.sys
   Machine Type: 34404 (X64)
     Time Stamp: 5632d4db Fri Oct 30 04:24:27 2015
           Size: c5000
       CheckSum: ce0f2
Characteristics: 22  
Debug Data Dirs: Type  Size     VA  Pointer
             CODEVIEW    25, 98310,   97110 RSDS - GUID: {BBFAAF05-FB9E-4C71-9000-15FF4A30AA8C}
               Age: 1, Pdb: Wdf01000.pdb
                   ??   4dc, 9834c,   9714c [Data not mapped]
     Image Type: FILE     - Image read successfully from debugger.
                 Wdf01000.sys
    Symbol Type: PDB      - Symbols loaded successfully from image path.
                 c:\websymbols\Wdf01000.pdb\BBFAAF05FB9E4C71900015FF4A30AA8C1\Wdf01000.pdb
       Compiler: C - front end [18.10 bld 40116] - back end [18.10 bld 40116]
    Load Report: private symbols & lines, not source indexed 
                 c:\websymbols\Wdf01000.pdb\BBFAAF05FB9E4C71900015FF4A30AA8C1\Wdf01000.pdb

WDF with vscode

Is it possible to build Hello World Windows Driver using visual studio code?

I have both Windows SDK and WDK installed, and I have attempted to configure it to look for msvc and the path for the headers.

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\km\\*",
                "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\wdf\\kmdf\\1.31\\*"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:\\Program Files (x86)\\Windows Kits\\10\\Tools\\sdv\\bin\\interceptor\\cl.exe",
            "cStandard": "c11",
            "cppStandard": "c++14",
            "intelliSenseMode": "windows-msvc-x64",
            "windowsSdkVersion": "10.0.19041.0"
        }
    ],
    "version": 4
}

Preprocessor usage bug in fxrequestbuffer.hpp

The file src/framework/shared/inc/private/common/fxrequestbuffer.hpp contains this block near the bottom:

#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
#include "FxRequestBufferKm.hpp"
#else if ((FX_CORE_MODE)==(FX_CORE_USER_MODE))
#include "FxRequestBufferUm.hpp"
#endif

The #else line isn't valid C/C++. The author meant #elif. I think the compiler is treating this as an #else followed by extra tokens it ignores.

You just need to change "#else if" -> "#elif"

Incorrect interval check in Mx::MxDelayExecutionThread()

Mx::MxDelayExecutionThread(
    __in KPROCESSOR_MODE  WaitMode,
    __in BOOLEAN  Alertable,
    __in PLARGE_INTEGER  Interval
    )
{
    UNREFERENCED_PARAMETER(WaitMode);

    LARGE_INTEGER intervalMillisecond;

    if (Interval < 0) // < =====
    {
        intervalMillisecond.QuadPart = -1 * Interval->QuadPart;
    }
    else
    {
        intervalMillisecond.QuadPart = Interval->QuadPart;
    }

    intervalMillisecond.QuadPart /= 10000;

    SleepEx((DWORD)intervalMillisecond.QuadPart, Alertable);
}

Interval is a pointer(PLARGE_INTEGER) that always >0

if (Interval->QuadPart < 0)
{
    intervalMillisecond.QuadPart = -1 * Interval->QuadPart;
}

???

Bug in FxTagTracker::UpdateTagHistory (reopen)

This issue is based on now closed #15, I am not able to reopen original issue.

"I found an error in the FxTagTracker :: UpdateTagHistory method. If the m_CurRefHistory counter overflows, the pos% TAG_HISTORY_DEPTH value becomes negative and points outside the m_TagHistory array. This causes BugCheck."

This problem is REAL and I tracked it down under WinDbg debugger. This problem occurs if tag tracing is enabled in the registry and the object is frequently referenced and dereferenced.

The explanation from wm1 user is meaningless. The m_CurRefHistory counter can overflows, of course. And pos variable has LONG data type which is signed. Thus pos can be negative. The C operator % returns negative remainder for negative dividend, see e.g.
https://docs.microsoft.com/en-us/cpp/cpp/multiplicative-operators-and-the-modulus-operator?view=msvc-160

The comment in the original source is wrong. There is simple solution: use ULONG data type for pos variable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.