Noob facing VS2015 issues from Peter's Blog

Hi all,

Complete noob here. I’m facing the issues Peter mentioned in his blog. https:</https:>
Our VS2013 licenses have expired, so I was forced to upgrade to VS2015. I’m migrating an NDIS driver project and facing issues. I followed Peter’s advice and changed the *.c files to *.cpp.

Issue 1: The NDIS macro #pragma NDIS_PAGEABLE_FUNCTION won’t link, but no big deal. I just called PAGED_CODE () inside the callbacks that need to be run at passive IRQ. I probably shouldn’t be using NDIS_PAGEABLE_FUNCTION anyway as it appears to be deprecated. It doesn’t give me any warnings or errors, so we’ll call that one resolved unless I’ve misunderstood something.

Issue 2: I faced an issue earlier in the project where the linker couldn’t find warning.h. It turns out I just had to include its path in Additional Dependencies. But now, I’m getting a “LNK1107 invalid or corrupt file: cannot read at 0x16D6” for line 1 of warning.h. I’m not sure what the issue is exactly.

Thanks for any advice,
Nate

I’m glad to hear the blog post was (somewhat) helpful.

I AM a bit confused though. For example, give. That NDIS_PAGEABLE_FUNCTION is a macro, that becomes a pragma (I guess??) I’m not sure how that would cause the linker any heartburn.

And you said the LINKER is having trouble finding warning.h? Isn’t that a C language header file, and thus rad by the compiler and not the linker?

Somehow, I feel like I’m missing something.

Peter
OSR
@OSRDrivers

> I’m glad to hear the blog post was (somewhat) helpful.
It is Peter. Actually, very helpful (and well written).

xxxxx@amplisine.com wrote:

Hi all,

Complete noob here. I’m facing the issues Peter mentioned in his blog. https:</https:>
Our VS2013 licenses have expired, so I was forced to upgrade to VS2015. I’m migrating an NDIS driver project and facing issues. I followed Peter’s advice and changed the *.c files to *.cpp.

Expired? How do compiler licenses expire? Unless you were using the
30-day trial package, I didn’t think Visual Studio had any timebombs.

Issue 1: The NDIS macro #pragma NDIS_PAGEABLE_FUNCTION won’t link, but no big deal. I just called PAGED_CODE () inside the callbacks that need to be run at passive IRQ. I probably shouldn’t be using NDIS_PAGEABLE_FUNCTION anyway as it appears to be deprecated. It doesn’t give me any warnings or errors, so we’ll call that one resolved unless I’ve misunderstood something.

Just to double check, don’t do this:
NDIS_PAGEABLE_FUNCTION(myFunc)
Do this:
#pragma NDIS_PAGEABLE_FUNCTION(myFunc)

Also, remember that any functions mentioned in an alloc_text pragma have
to be declared with C linkage, not C++. You need this:
extern “C” {
void MyFunc(…);
}

Issue 2: I faced an issue earlier in the project where the linker couldn’t find warning.h. It turns out I just had to include its path in Additional Dependencies. But now, I’m getting a “LNK1107 invalid or corrupt file: cannot read at 0x16D6” for line 1 of warning.h. I’m not sure what the issue is exactly.

The linker does not need warning.h. Warning.h is a compiler include
file. If you included it in the linker’s AdditionalDependencies, then
the linker assumed it was a compiled object file. No wonder it complained.

Remove it from the AdditionalDependencies, and then tell us what error
you get.

How much coding have you done, prior to diving in to kernel code?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hey guys sorry it took me so long to get back.

Expired? How do compiler licenses expire? Unless you were using the 30-day trial package, I didn’t think Visual Studio had any timebombs.

I have both VS2013 and VS2015 installed. VS2013 seems to have reverted to a trial package thus the time bomb. VS2015 works fine. IT tells me that’s just the way it is. IDK.

Also, remember that any functions mentioned in an alloc_text pragma have to be declared with C linkage, not C++. You need this: extern “C” { void MyFunc(…); }

I’m just becoming aware of that. I’m getting a bunch of extern C related issues. I’ll get back to them in a sec.

The linker does not need warning.h. Warning.h is a compiler include file. If you included it in the linker’s AdditionalDependencies, then the linker assumed it was a compiled object file. No wonder it complained.

I set my files back to *.c extension to suppress some of the .cpp related issues for the moment. Without the warning.h include, I’m getting “LINK2019 unresolved external symbol” every time I make an NDIS function call (e.g. LNK2019 unresolved external symbol NdisMRegisterMiniportDriver referenced in function DriverEntry). I took a look at the NDIS filter template. It adds ndis.lib to AdditionalDependencies. When I do that, it resolves all of the LNK2019 issues. That makes a great deal more sense than what I was doing and jives with what Tim said.

How much coding have you done, prior to diving in to kernel code?
I’m a CpE grad student if that tells you anything. You know how it is. Projects just outside of your comfort zone.

Ok, with my files set back to *.cpp intellisense is complaining windot11.h. Specifically it says “extra text after expected end of number” anywhere there is a DEFINE_NWF_GUID. However, the main issue another LNK2019 (i.e. Code: LNK2019 Description: unresolved external symbol DriverEntry referenced in function FxDriverEntryWorker File: WdfDriverEntry.lib (stub.obj) Line:1 ).

To that end, DriverEntry looks like this:

///////driver.h///////
DRIVER_INITIALIZE DriverEntry;

//////driver.c////////
Use_decl_annotations
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{

}

I’ve never done a mixed c and cpp environment. Please tell me more about the extern “C” calls I need to make. Thanks again for all the help.

-Nate

xxxxx@amplisine.com wrote:

> How much coding have you done, prior to diving in to kernel code?
I’m a CpE grad student if that tells you anything.

Actually, it doesn’t. That acronym is grossly overloaded. But, it’s
not relevant.

Ok, with my files set back to *.cpp intellisense is complaining windot11.h. Specifically it says “extra text after expected end of number” anywhere there is a DEFINE_NWF_GUID. However, the main issue another LNK2019 (i.e. Code: LNK2019 Description: unresolved external symbol DriverEntry referenced in function FxDriverEntryWorker File: WdfDriverEntry.lib (stub.obj) Line:1 ).

To that end, DriverEntry looks like this:

///////driver.h///////
DRIVER_INITIALIZE DriverEntry;

//////driver.c////////
Use_decl_annotations
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{

}

I’ve never done a mixed c and cpp environment. Please tell me more about the extern “C” calls I need to make. Thanks again for all the help.

C++ compilers have to add type information to all of the names they
create, partly to add some link-time type checking, partly to handle
overloads. In a C program, your declaration above would have created
the external name _DriverEntry, and that is exactly what the KMDF
framework is trying to link to. However, the name your C++ compiler
created for the linker is actually:
?DriverEntry@@YAJPEAU_DRIVER_OBJECT@@PEAU_UNICODE_STRING@@@Z

So, the name _DriverEntry is undefined, and the linker complains.

The typical driver doesn’t have any externally linked names, so this
hasn’t historically been a problem. With KMDF, however, things have
changed. DriverEntry gets referenced externally, PLUS all of the
callback names have typedefs that assume C linkage. You do that this way:

extern “C” {
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_UNLOAD My_EvtDriverUnload;
EVT_WDF_DRIVER_DEVICE_ADD My_EvtDeviceAdd;
EVT_WDF_OBJECT_CONTEXT_CLEANUP My_EvtDeviceCleanup;
}

Or, if you find this more appealing:

extern “C” DRIVER_INITIALIZE DriverEntry;
extern “C” EVT_WDF_DRIVER_UNLOAD My_EvtDriverUnload;
extern “C” EVT_WDF_DRIVER_DEVICE_ADD My_EvtDeviceAdd;
extern “C” EVT_WDF_OBJECT_CONTEXT_CLEANUP My_EvtDeviceCleanup;


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim’s suggestion worked. I realized you also have to do this with macros. FYI you must use {} when you call extern “C” with a macro.

//This works
extern “C” {
#pragma Macro(arguments)
}

//This doesn’t
extern “C” #pragma Macro(arguments)

Thanks for your help all!

-Nate

xxxxx@amplisine.com wrote:

Tim’s suggestion worked. I realized you also have to do this with macros. FYI you must use {} when you call extern “C” with a macro.

//This works
extern “C” {
#pragma Macro(arguments)
}

//This doesn’t
extern “C” #pragma Macro(arguments)

Well, no; the “extern” declaration only affects declarations that
produce external names. #pragmas are not affected by it, nor are macro
expansions.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Good news! You don’t have to do this anymore in KMDF.

I haven’t put a role type declaration in an “extern C” block in ages.

Peter
OSR
@OSRDrivers

Well, you’re right. I removed the extern declarations from the macros. I think it wasn’t the macro, but the fact that the macro used the function name (e.g. #pragma NDIS_PAGEABLE_FUNCTION(MiniportDriverUnload)).

Good to know, but I think you still have to do it for NDIS calls though. I get this error if I remove extern “C” from MINIPORT_UNLOAD MiniportDriverUnload;

‘MiniportDriverUnload’: alloc_text/same_seg applicable only to functions with C linkage

Thanks again
-Nate

Funny… this brings us back to another thread here where we were just talking about this.

So… you need the “extern C” because you’re using the NDIS_PAGEABLE_FUNCTION macro.

All NDIS_PAGEABLE_FUNCTION does is

#define NDIS_PAGEABLE_FUNCTION(_F) alloc_text(PAGE,_F)

and in terms of alloc_text, MSDN tells us:

“The alloc_text pragma does not handle C++ member functions or overloaded functions. It is applicable only to functions declared with C linkage ? that is, functions declared with the extern “C” linkage specification. If you attempt to use this pragma on a function with C++ linkage, a compiler error is generated.”

Soooo…

Once again, allow me to babble on of my favorite pieces of advice: Unless you’re writing some sort of big, behemoth, driver with sections that aren’t used for long periods of time… just make the whole thing non-paged and make your life easier and less prone to error.

Peter
OSR
@OSRDrivers

+1

Jan

On 9/29/15, 6:26 AM, “xxxxx@lists.osr.com on behalf of xxxxx@osr.com” wrote:

>Once again, allow me to babble on of my favorite pieces of advice: Unless you’re writing some sort of big, behemoth, driver with sections that aren’t used for long periods of time… just make the whole thing non-paged and make your life easier and less prone to error.
>