I have a driver that runs in the kernel of a Windows Embedded Compact 2013. The driver is loaded with the "Drivers\BuiltIn" registry key. It accesses a set of HW-registers that are mapped with MmMapIoSpace.
The access to the hardware has some problems. That's why I would like to develop the hardware access in a user mode program and debug the problems. I created a program with VS2013 for that purpose. That's the way we used to go with Windows CE 5.0.
The driver maps the physical address with MmMapIoSpace to the process address space. My program should do the same or something similar. Unfortunately this doesn't work in my program. MmMapIoSpace returns NULL, LastError=87 (invalid parameters). Even CreateStaticMapping returns NULL.
How can I access memory mapped register in WEC2013 without building a new platform for each iteration?
MmMapIoSpace doesn't work in applications anymore since WinCE6.
You maybe could create a driver which maps your hw-register to your user process. Your user process would then obtain this pointer by an ioctl call to this driver.
We mapped some external memory to an application with this method.
VirtualAllocCopyEx() can create a mapping to a specified process.
Hope, this helps. Greetings.
Corresponding to timmfs answer I implemented this code in the driver's XXX_IOControl function:
PHYSICAL_ADDRESS PhysAddress = { 0 };
PhysAddress.LowPart = phys_address;
PVOID pRegister = MmMapIoSpace(PhysAddress, phys_size, FALSE);
HANDLE hCallerProcess = (HANDLE)GetCallerVMProcessId();
HANDLE hCurrentProcess = (HANDLE)GetCurrentProcessId();
PVOID UserSpaceAddress = VirtualAllocCopyEx(hCurrentProcess, hCallerProcess, pRegister, shys_size, PAGE_NOCACHE);
This excerpt shows some solutions for pitfalls I met. So I show how I get all the parameters.
Related
I am building a embedded device that will communicate to the outside world by virtual COM. I have the descriptor and all the callbacks for the USB set up correctly and COM is working - well kind of. The problem is that when I issue the GetCommState command for the COM I get a semi valid struct back and when one fixes only couple of parameters (like setting the speed and 8N1) and try to reconfigure the port by calling SetCommState the actions fails with: 'A device attached to the system is not functioning.'
If one continues to use the port it just work - all writes and reads - without a problem. But the issue is that most libraries try to reconfigure the port by first issuing the GetCommState and then SetCommState - pyserial and C# both do it in this way.
My question is where do the "default" configuration for COM comes form?
In the USB ACM CDC standard there are (optional) class requests for SET and GET COMM feature but I can see (from USB sniffer) that they are never called (I tried with capabilities for USB ACM CDC set to 0x06 (that is without SET/GET COMM) and 0x07 (with SET/GET COMM) but in no case I get a class request from the driver). So the driver must take the config from somewhere else, does anybody knows from where or how?
I am using an NXP LPC and Windows 10 with usbser.sys driver on other end.
What I already checked is:
compared the USB descriptor to the working one - they are the same
checked the USB traffic - the enumeration and communication looks the same
without doing GetCommState and SetCommState the COM is working without problem
I attached the content of the DCB struct for working sample (left) and my (right). I do not understand where do the marked values come from? Who sets them?
The settings should come from the port driver - you can view and set default values in the Windows Device Manager. In your case, it would seem that flow control with RTS/CTS is enabled (left picture), which might be something that your USB adapter uses internally. If it works, then leave those settings as they were.
I'd advise to do like this:
Always check the result of each API function you call!
Call CreateFile to get the port handle.
Optionally call GetCommTimeouts and store the result in a zero-initialized struct like COMMTIMEOUTS com_timeouts = {0};. Change members of the struct as needed, then call SetCommTimeouts.
Create an (almost) zero-initialized struct DCB dcb = { .DCBlength = sizeof(DCB) }.
Call GetCommState on this struct.
Set baudrate, parity, stop bits etc as required. Leave other members as they were.
Call SetCommState.
I have developed a custom credential provider. This credential provider uses 1) camera 2) facial sdk to match the user. Once the user is matched account name is populated and CredentialsChanged signal is triggered. I have customized samplehardwareeventcredentialprovider
to achieve this functionality. This works fine with few of the machine ( all windows 10). When I tried to execute this another machine ( different brand), I get the following exception randomly and makes the screen go black , unstable login screen. All the dependencies are in place but it is not stable at all.
I have turned off the winbio service, disabled many of default credential providers but I face the same issue.
My Flow:
I initiate the facial identification flow in CSampleCredential::Initialize api and once it is identified, update the value for rgFieldStrings[SFI_USERNAME]
In the following method, after completing CSampleCredential::Initialize , I use CSampleProvider::OnConnectStatusChanged method to trigger login window. If everything works as expected, it launches login window with user name auto populated. The entire flow works file, but it is not stable in few machine.
HRESULT CSampleProvider::SetUsageScenario(
__in CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
__in DWORD dwFlags
)
Am I doing something fundamentally wrong here?
Any pointers will be helpful! Thanks
I generated localdump by following Steps to Catch a Simple “Crash Dump” of a Crashing Process
By analyzing the log, it was evident that there was a heap corruption. By mistake, malloc allocation was done for the size of 4. Actually this allocation should be of size 260. When the memory is accessed beyond this size, it was triggering the random crash based on the input data.
Original code with bug:
uint8_t* data = (uint8_t*)malloc(sizeof(MAX_PATH));
Fixed code:
uint8_t* data = (uint8_t*)malloc(MAX_PATH*sizeof(uint8_t));
The docs for the SetupDiSetDeviceRegistryProperty function say,
The following values are reserved for use by the operating system and
cannot be used in the Property parameter ...
SPDRP_HARDWAREID
However, there are lots of examples of code out there, including MS DevCon utility which uses this function with the SPDRP_HARDWAREID parameter, ie:
SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)hwIdList,
(lstrlen(hwIdList)+1+1)*sizeof(TCHAR)))
They also have an article which suggests doing so:
If an installer detects a non-PnP device, the installer should select a driver for the device as follows: create a device information element (SetupDiCreateDeviceInfo), set the SPDRP_HARDWAREID property by calling SetupDiSetDeviceRegistryProperty
I'd like to (and do) use this function to set Hardware ID for my virtual device. The question is - is it a typo in the manual, or it's some sort of unsupported behavior and therefore it can stop working any time?
TL;DR: If you're creating a root-enumerated device node, you're free to set SPDRP_HARDWAREID/SPDRP_COMPATIBLEIDS yourself by calling SetupDiSetDeviceRegistryProperty. Otherwise you're not allowed to do so.
This was an error in the docs that was fixed at some point.
Today the docs of SetupDiSetDeviceRegistryProperty read:
SPDRP_HARDWAREID or SPDRP_COMPATIBLEIDS can only be used when DeviceInfoData represents a root-enumerated device. For other devices, the bus driver reports hardware and compatible IDs when enumerating a child device after receiving IRP_MN_QUERY_ID. [Emphasis mine]
... which is exactly what DevCon does.
What is the purpose of this flag (from the OS side)?
Which functions use this flag except isDebuggerPresent?
thanks a lot
It's effectively the same, but reading the PEB doesn't require a trip through kernel mode.
More explicitly, the IsDebuggerPresent API is documented and stable; the PEB structure is not, and could, conceivably, change across versions.
Also, the IsDebuggerPresent API (or flag) only checks for user-mode debuggers; kernel debuggers aren't detected via this function.
Why put it in the PEB? It saves some time, which was more important in early versions of NT. (There are a bunch of user-mode functions that check this flag before doing some runtime validation, and will break to the debugger if set.)
If you change the PEB field to 0, then IsDebuggerPresent will also return 0, although I believe that CheckRemoteDebuggerPresent will not.
As you have found the IsDebuggerPresent flag reads this from the PEB. As far as I know the PEB structure is not an official API but IsDebuggerPresent is so you should stick to that layer.
The uses of this method are quite limited if you are after a copy protection to prevent debugging your app. As you have found it is only a flag in your process space. If somebody debugs your application all he needs to do is to zero out the flag in the PEB table and let your app run.
You can raise the level by using the method CheckRemoteDebuggerPresent where you pass in your own process handle to get an answer. This method goes into the kernel and checks for the existence of a special debug structure which is associated with your process if it is beeing debugged. A user mode process cannot fake this one but you know there are always ways around by simply removing your check ....
I'm updating a functioning KMDF driver for a PCI device, using WinDDK 7600.16385.1 and OSR's ddkbuild.cmd, targeting WLH, testing on Win7 x86 and x64.
I'm attempting to retrieve the DEVPKEY_Device_LocationPaths property.
The Device Manager Device Properties Details tab displays the expected value in "Location Paths" ...
PCIROOT(0)#PCI(1C00)#PCI(0000)#PCI(0200)#PCI(0000)#PCI(0900)#PCI(0000)#PCI(0400)
... but calling IoGetDevicePropertyData() from the EvtDriverDeviceAdd handler ...
PDEVICE_OBJECT pWdmPDO = WdfFdoInitWdmGetPhysicalDevice( pDeviceInit );
[... WdfDeviceCreate succeeds ...]
WCHAR wszLocationStrings[128] = { 0 }; // Temporary, just to confirm DDI works
ULONG ulRequiredSize = 0;
DEVPROPTYPE devPropType = 0;
status = IoGetDevicePropertyData( pWdmPDO,
&DEVPKEY_Device_LocationPaths,
LOCALE_NEUTRAL,
/*ulFlags*/ 0,
sizeof(wszLocationStrings),
wszLocationStrings,
&ulRequiredSize,
&devPropType );
... always returns STATUS_OBJECT_NAME_NOT_FOUND.
I have tried ...
calling IoGetDevicePropertyData() for other DEVPKEY_Device_* values. The result is the same.
calling IoGetDevicePropertyData() in the EvtDevicePrepareHardware handler. The result is the same.
calling WdfDeviceWdmGetPhysicalDevice() to retrieve the PDO. The result is the same
WdfDeviceAllocAndQueryProperty(). It works correctly but does not provide the info I require.
WdfFdoQueryForInterface( GUID_PNP_LOCATION_INTERFACE ). It works correctly but only provides the current node (i.e. "PCI(0400)")
Searching for sample code that calls IoGetDevicePropertyData. I found the Windows CDROM Storage Class Driver sample but it doesn't appear to do anything I haven't tried already.
So ... what am I missing?
I found a MS PnP support email address in a WinHEC 2006 powerpoint and received a response from Microsoft ...
On Vista and Windows 7, IoGetDevicePropertyData cannot retrieve all the DEVPKEY
properties that user-mode can. There is no way for you to directly retrieve that
full path as created by the operating system from kernel mode.
For further questions, the Windows Hardware WDK and Driver Development forum
(http://social.msdn.microsoft.com/Forums/en-US/wdk/threads ) is a good place to
ask driver development questions.
... to which I responded ...
Thank you very much to your quick response!
It would be very helpful if the IoGetDevicePropertyData online docs could be updated
to include a list of the DEVPKEY properties that are supported and restrictions on
their availability (i.e. only after Start IRP completes as noted in the WinHEC
powerpoint)
And thanks for the link to the forum, I'll start there next time.