I'm trying to write a kmdf driver to target a custom PCIe board. On following the default project that Microsoft provides, I made a few minor changes to the .inf file, mainly changing the names of strings and providing the hardware ID of our PCIe board.
Deploying the driver works as it should. The driver installs and shows up on the device manager, but it says that it didn't install correctly or it may be corrupted.
On debugging, I see that WdfDriverCreate fails with an error of 0xC000009A, which means insufficient resources.
For reference, this is the generated code that the kmdf template project makes for you, which is what I am currently running:
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING( DriverObject, RegistryPath );
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//
// Register a cleanup callback so that we can call WPP_CLEANUP when
// the framework driver object is deleted during driver unload.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
attributes.EvtCleanupCallback = CIPDriverEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&config,
CIPDriverEvtDeviceAdd
);
KdPrint(("CIP: Driver Entry\n"));
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
WDF_NO_HANDLE
);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
KdPrint(("CIP: WdfDriverCreate failed with status - 0x%x\n", status));
WPP_CLEANUP(DriverObject);
return status;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
return status;
}
My first question is, What would cause this?
I attempted to dump a log after the error is raised by running
!wdfkd.wdflogdump mydriver.sys
But it never works. I ensured that all symbol paths are loaded properly, as shown below
fffff880`05fdd000 fffff880`05fe6000 CIPDriver (private pdb symbols) C:\Users\jimmyjoebobby\Documents\Visual Studio 2013\Projects\CIPDriver\x64\Win7Debug\CIPDriver.pdb
22: kd> lm m wdf*
start end module name
fffff880`00e5e000 fffff880`00f20000 Wdf01000 (pdb symbols) c:\winsymbols\Wdf01000.pdb\03FC6AA4329F4372BE924775887225632\Wdf01000.pdb
fffff880`00f20000 fffff880`00f30000 WDFLDR (pdb symbols) c:\winsymbols\wdfldr.pdb\9674B20D2E5B4E7AA2DE143F642A176E2\wdfldr.pdb
Where "CIPDriver" is my driver.
On running the dump command, this is the output:
22: kd> !wdfkd.wdflogdump CIPDriver.sys
Trace searchpath is:
Trace format prefix is: %7!u!: %!FUNC! -
TMF file used for formatting log is: C:\WinDDK\7600.16385.1\tools\tracing\amd64\wdf01000.tmf
Log at fffffa80356232f8
Gather log: Please wait, this may take a moment (reading 0 bytes).
% read so far ...
warn: The log could not be accessed
hint: Are the symbols the WDF library available?
hint: The log is inaccessable after driver unload.
And the output of .sympath
22: kd> .sympath
Symbol search path is: C:\Users\jimmyjoebobby\Documents\Visual Studio 2013\Projects\CIPDriver\Win7Debug;C:\winsymbols
Expanded Symbol search path is: c:\users\jimmyjoebobby\documents\visual studio 2013\projects\cipdriver\win7debug;c:\winsymbols
Where C:\winsymbols is a cache of Microsofts's symbols which I acquired by following the guide here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff558829(v=vs.85).aspx
My second question is, how do I correctly setup the debugger to dump out the logs?
Thanks
I don't quite understand why this helps, but if I turned off KMDF verifier under
[DriverName] Package -> Properties -> Configuration Properties -> Driver Install -> KMDF Verifier -> Enable KMDF Verifier
And deploy the driver, it works. If I turn that on, it fails. I deployed my driver a few times toggling that option on and off and it always fails when it's on.
I posted this question along with my findings. Maybe someone there could answer why this is the case: https://www.osronline.com/showthread.cfm?link=277793
Related
I am accessing a c++ dll library (I don't have the source code) from c++ code. I use this library to mount a usb device so I can access the files on the device. This code worked well in VS2010 but since we updated to VS2013 it no longer works. Here is my question. What differences between VS2010 and VS2013 might cause this to fail or what settings might cause this to fail?
Here is what I observe when running the code:
The LoadLibary call returns a module handle
The GetProcAddress seems to return a valid procedure address
Invoking the dyn_Open_Device always returns false with VS2013 it
almost always returned true in VS2010.
After calling dyn_Open_Device, GetLastError returns 2
(ERROR_FILE_NOT_FOUND)
Here is the code:
typedef bool(*PFUNC_Open_Device)();
DWORD dwError = GetLastError();
BOOL bSuccess = SetDllDirectory(_T("C:\\Users\\steve epp\\Desktop\\EH16\\sdk1.1\\lib\\"));
// Step 2: Dynamically load the dll
HMODULE m_hModule = LoadLibrary("eeyelog_protocol_v1.0.dll");
dwError = GetLastError();
// Handle the case that the dll is not found
if (m_hModule == NULL)
{
dwError = GetLastError();
if (dwError == ERROR_MOD_NOT_FOUND)
{
CString msg = "Unable to load eeyelog_protocol_v1.0.dll.";
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
}
}
PFUNC_Open_Device dyn_Open_Device = (PFUNC_Open_Device)GetProcAddress(m_hModule, "Open_Device");
dwError = GetLastError();
bool ret = dyn_Open_Device();
dwError = GetLastError();
Here is the DUMPBIN results:
DUMPBIN /EXPORTS "C:\Users\steve epp\Desktop\EH16\sdk1.1\lib\eeyelog_protocol_v1.0.dll"
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file C:\Users\steve epp\Desktop\EH16\sdk1.1\lib\eeyelog_protocol_v1.0.dll
File Type: DLL
Section contains the following exports for eeyelog_protocol_v1.0.dll
00000000 characteristics
59CC4F90 time date stamp Wed Sep 27 18:25:36 2017
0.00 version
1 ordinal base
33 number of functions
33 number of names
ordinal hint RVA name
1 0 000010A0 Check_Device_state
2 1 000011D0 Close_Device
3 2 000012E0 Login
4 3 000011A0 Open_Device
I solved the problem with the help of Process Monitor. In the Process Monitor’s Event Properties dialog under the Process tab I could see that eeyelog_protocol_v1.0.dll was running and its dependency libusb0.dll was also running. However, the running libusb0.dll was the wrong version an older version. Once I ran the correct version then everything worked again. Running the code through the debugger it was picking up the wrong version of libusb0.dll from the directory containing the executable. So make sure you are loading and running the right version. I had the correct version in the path I set with SetDllDirectory but it was using the wrong version because it found that one first.
I had never used Process Monitor before. It is a very helpful Microsoft SysInternals tool. It can be found downloaded from https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
i,m new to kext programming so my problem is:
i,m running macOS 10.11.6 i have turned SIP off but when i try to load my
kext using kextload and using the -v flag i get that my kext was successfully loaded:
*Requesting load of /private/tmp/kern.kext.
/private/tmp/kern.kext loaded successfully (or already loaded).*
and to check that my kext was loaded i have used kextstat :
152 0 0xffffff7f82db3000 0x2000 0x2000 com.SPX.kext.kern (1) 299868F4-9962-362D-AE3D-09579B6780DB <4>
but when i tail my kernel logs from: /var/log/system.log
using the command : tail -f /var/log/system.log
i see that error:
MacBook-Pro com.apple.kextd[47]: kext signature failure override
allowing invalid signature -67050 0xFFFFFFFFFFFEFA16 for kext
"/private/tmp/kern.kext"
my kext is a simple hello world kext and there's my code
#include <mach/mach_types.h>
#include <libkern/libkern.h>
kern_return_t kern_start(kmod_info_t * ki, void *d);
kern_return_t kern_stop(kmod_info_t *ki, void *d);
kern_return_t kern_start(kmod_info_t * ki, void *d)
{
printf("hello world");
return KERN_SUCCESS;
}
kern_return_t kern_stop(kmod_info_t *ki, void *d)
{
printf("bye kext");
return KERN_SUCCESS;
}
thanks in advance for any help
edit:
so after many test its look like the kext was loaded successfully but when it comes to the code sign issue i went through Xcode Build Settings and there i found code signing so in the code signing there's code signing identity so i set it to Don't code sign and i build it with using Xcode build tool xcodebuild -configuration Debug -target kern
but still no progress till now, so i hope someone help at least give a link or anything .
The output you're getting suggests that the kext is being loaded - code signing is not your problem.
I do notice however that your printf() calls contain no line termination. (\n) Not outputting whole lines will cause the messages to be buffered for longer than you'd expect, and run into other messages. With something like this, it should work, and you should see your messages in the system log:
printf("hello world\n");
My project at work debugged under 10.6/Xcode 3.2.5 works fine but at home the same project run under Lion/Xcode 3.2.5 tosses dozens of these
unable to read unknown load command 0x26
messages in the debugger. Any ideas on what I can do to determine what GDB is complaining about? It still "seems" to work, but I have no idea what might be missing or wrong.
Note this is a regular OSX app, not iOS.
The message comes from bfd/mach-o.c:
switch (command->type)
{
case BFD_MACH_O_LC_SEGMENT:
if (bfd_mach_o_scan_read_segment_32 (abfd, command) != 0)
return -1;
break;
.....
default:
fprintf (stderr, "unable to read unknown load command 0x%lx\n",
(unsigned long) command->type);
break;
}
The warning says that BFD cannot recognize the Mach-O section load command it has encountered.
Looking at bfd/mach-o.h where known load commands are described, we find that commands there range from 0x1 to 0x18, yet nothing beyond.
Mac OS X (Lion) defines load constants in /usr/include/mach-o/loader.h (available if you've installed XCode), from 0x1 to 0x27. Therefore, the most logical explanation to seeing the warnings for load commands > 0x18 appears to be the lack of the said codes in BFD's own header.
Also, for follow-ups consider looking at: https://bugs.launchpad.net/tarantool/+bug/1018356
I am trying to launch an external application from within my Win32 application but it's failing. Following is the code I am using:
HINSTANCE instance = ShellExecute(NULL, _T("open"), _T("loader.exe"), NULL, NULL, SW_SHOWNORMAL);
if((int)instance <= 32)
{
_cprintf("Error = 0x%X\n", GetLastError());
return 0;
}
The instance value I get is 0x00000002 and GetLastError returns 0x2. The same code works when I try to launch other applications like iTunes.exe or cmd.exe. Does it has anything to do with external application? By the way, win32 application and loader.exe application are located in the same folder.
Any help would be highly appreciated.
Farooq-
Well, error 0x2 is ERROR_FILE_NOT_FOUND
Looks like it can't find "loader.exe"
Error 2 is "File not found":
http://msdn.microsoft.com/en-us/library/ms681382(v=vs.85).aspx
I'm guessing it can't find loader.exe.
Put loader.exe somewhere in the search path, or provide the full path. That is how to avoid this file not found error. Windows error codes are all documented on MSDN.
I am running on a Win2K8R2 system that has Microsoft's NFS client installed in addition to the Windows CIFS client.
Given a UNC path (which the NFS client does support with caveats) I need to be able to tell if operations on the path would be handled by the CIFS or NFS client. WNetGetResourceInformation() would seem to provide this, but I have not been able to get it to work when the UNC path is to an NFS server.
Sample code:
int GetResourceInformation(TCHAR* path, void* buffer, DWORD* size)
{
TCHAR* p = NULL;
NETRESOURCE nr;
memset(&nr, 0, sizeof(nr));
nr.lpRemoteName = path;
DWORD dwRetVal = WNetGetResourceInformation(&nr, buffer, size, &p);
if(dwRetVal == NO_ERROR)
{
NETRESOURCE* tmp = (NETRESOURCE*)buffer;
wprintf(L"%s provider=%s system=%s\n", path, tmp->lpProvider, (p == NULL) ? L"<null>" : p);
}
else
{
wprintf(L"WNetGetResourceInformation failed for %s with error: %u\n", path, dwRetVal);
}
return dwRetVal;
}
I have also tried filling in the NETRESOURCE lpProvider and/or dwType fields as suggested in the doc but with no change in behavior.
If I pass the function a CIFS UNC path it succeeds. If I pass it an NFS UNC path it fails with error 487 "Attempt to access invalid address.". I also tried passing the native NFS path style hostname:/export/file but this fails with error 67 "The network name cannot be found."
I found the following sample for using WNetAddConnection2() with NFS but this code also fails for me with error 50 "The request is not supported". I can successfully mount the export using either "net use" command or the NFS-specific mount.exe tool provided by Microsoft.
Finally, WNetOpenEnum/WNetEnumResource does not return any NFS provider information for me or even show any connected drives that I have mapped via "net use" or mount.exe.
My general question is, has anyone had better success using the the WNet APIs with the NFS provider? Specifically, is there some mechanism I can use to determine the provider for a remote path?
Are you building as x86 or x64? It looks like the WNet* API's don't work correctly for NFS shares from an x86 process under WOW64. You can see this without writing code - if you have an NFS share mounted, "C:\windows\system32\net use" will show it, where "C:\windows\syswow64\net use" will not. Filesystem access seems OK the 32-bit process, but none of the APIs work.
Even built as x64, using a NULL lpProvider is inconsistent for me. Half the time it doesn't work, the other half it waits about 5 seconds before returning.
Calling WNetGetResourceInformation twice, once with a lpProvider of "NFS Network" and once with "Microsoft Windows Network" works consistently and returns instantly.