Custom driver acess in UWP using win32 - winapi

Windows 10 IoT documents calling a custom device using CreateFile and DeviceIoControl.
https://developer.microsoft.com/en-us/windows/iot/Samples/CustomDeviceAccessor
Is this same available for an Enterprise App in Windows 10?
What we have is a custom USB hardware based on Cypress Fx2. We also have custom driver that uses shared memory for some very efficient Isochronous transfers. All works fine with Win32. Now we would like to move to UWP.
We prefer the programming model of the win32 APIs to Windows.Devices.Usb as the later would take us years in porting. Also we need the performance of shared memory and Isochronous support.
Permitting our device to be accessed using Win32 as documented in Windows IoT would be immensely beneficial.
Those guidelines recommended in IoT do not seem to work in the desktop. I am unable to "Grant Access to AppContainer Processes" by modifying the Security registry key and CreateFile fails with "access denied".
Am I missing something or CreateFile is entirely blocked in the UWP even for enterprises?
TIA
Ravi

Using platform/Invoke I just succeeded using Win32 APIs, CreateFile and DeviceIoControl from a VB.net UWP in windows 10 desktop to access our custom Cypress FX2 based USB device using our own WDM driver.
Method 1 documented in https://developer.microsoft.com/en-us/windows/iot/Samples/CustomDeviceAccessor
works fine for the desktop too.
Here is a frame grab of the command prompt to make registry settings to grant Access to "AppContainer Processes" to our hardware!
C:\WINDOWS\system32>schtasks /delete /tn DeviceAC /f
ERROR: The system cannot find the file specified.
C:\WINDOWS\system32>schtasks /create /RU SYSTEM /SC ONCE /TN DeviceAC /TR "reg import c:\data\deviceac.reg" /ST 00:00
WARNING: Task may not run because /ST is earlier than current time.
SUCCESS: The scheduled task "DeviceAC" has successfully been created.
C:\WINDOWS\system32>schtasks /run /tn DeviceAC /I /Hresult
SUCCESS: Attempted to run the scheduled task "DeviceAC".
C:\WINDOWS\system32>schtasks /query /tn DeviceAC
Folder: \
TaskName Next Run Time Status
======================================== ====================== ===============
DeviceAC N/A Ready
C:\WINDOWS\system32>reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_0547&PID_BC02\6&59cb9c4&0&4" /v Security
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_0547&PID_BC02\6&59cb9c4&0&4
Security REG_BINARY 010004900000000000000000000000001400000002006000040000000000140000000010010100000000000512000000000018000000001001020000000000052000000020020000000014000000001001010000000000050B0000000000180000000010010200000000000F0200000001000000
C:\WINDOWS\system32>schtasks /delete /tn DeviceAC /f
SUCCESS: The scheduled task "DeviceAC" was successfully deleted.
CreateFile and DeviceIoControl work like charm. We have clean fast and synchronous Win32 code.
No crap like
task <UINT32> CUsbDev::getDeviceInfo()
{
return create_task(DeviceInformation::FindAllAsync(UsbDevice::GetDeviceSelector(0x0547, 0xAB02)))
.then([this](DeviceInformationCollection^ deviceInformationCollection) -> UINT32
{
if (deviceInformationCollection->Size > 0)
{
DeviceInformation^ di = deviceInformationCollection->GetAt(0);
String^ s = di->Id;
create_task(UsbDevice::FromIdAsync(s))
.then([this, di](UsbDevice^ usbDevice)
{
String^ s;
if (usbDevice != nullptr)
{
UsbDeviceDescriptor^ devDesc = usbDevice->DeviceDescriptor;
s = devDesc->VendorId.ToString();
s += devDesc->ProductId.ToString();
return 0;
}
else
{
return 1;
}
});
}
else
{
return 10;
}
});
}
While first method is for the developer this next method should be useful for production
The same registry settings is possible through an .inf declaration as mentioned in this link
"Specifying Access Controls for a Particular Device in the DDINSTALL.HW Section"
http://www.osronline.com/article.cfm?article=508
Off track:
If our good friend Bill was at the helm of affairs he would have never allowed junk like C++/CX extensions to have come in the first place. What sort of computer programming is it to create a thread (or task) for each procedure. Children are running away looking at the hats and decorations in C++/CX code. A clean C++ was given to this generation and what they gave to the next is unforgivable. Bill should have a glimpse of the code generated by his company today.
Now they are taking about C++/WinRt to clean the rubbish.
I believe the core of UWP is in plain Win32 C (C++) code. It is time for a complete circle to bring back VB6 to access UWP code directly, cleanly and efficiently.
Ravi

Related

Suspend Windows Shutdown until application finished it´s work VB.Net

i wrote a little desktop utility which automatically detects an USB Stick which contains updates for antivirus patterns and software packages. It can either perform those updates on detection or on system shutdown/restart and here comes the problem...
I am not able to get the suspended shutdown to work properly..
If i am using this code my application sucessfully blocks the windows shutdown, but won´t perform the updating process.
' >>>>Process Windows Shutdown<<<<
If m.Msg = WM_QUERYENDSESSION OrElse m.Msg = WM_ENDSESSION Then
ShutdownBlockReasonCreate(Me.Handle, "Performing #### and Kasperksy Updates...")
UnZipKit()
ShutdownBlockReasonDestroy(Me.Handle)
Return
End If
I already found out that i need to return FALSE somewhere, but i can´t figure out how. The Microsoft statement can be found here: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms700677(v=vs.85)
As for additional information, if i won´t include the RETURN windows shutdown won´t be delayed what so ever...
A different approach is to write a shutdown script.
Like here described https://learn.microsoft.com/en-us/previous-versions/technet-magazine/dd630947(v=msdn.10)
a vbs script can do almost anything analogue to vb net-

Direct3DCreate9Ex returns D3DERR_NOTAVAILABLE (0x8876086a) when running as Windows Service

For some reasons, I have to create D3D9 in my program, which is running as a service.
But I got D3DERR_NOTAVAILABLE for the following code:
ATL::CComPtr<IDirect3D9Ex> d3d9 = nullptr;
HRESULT hr = ::Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9);
And it works if it's not running in a service.
I saw someone success to do this by checking Allow service to interact with desktop in the Control Panel, but it doesn't work for me.
Is there any setting I have to mention?
In Windows Vista and later, Windows Services run in an isolated context (called 'session 0 isolation') to reduce threats from malware. In some cases, you can create a NULL device and possibly a WARP device, but Direct3D GPU access from a Windows Service is not available until Windows 8.
See KB 978635

addmonitor win32 call fails with lasterror 5

I have created a very small win32 console application (AddPrintMonitor.exe) that does nothing more than makes a call to AddMonitor. Here is a small snippet:
MONITOR_INFO_2 m_MonitorInfo2;
m_MonitorInfo2.pName = lpMonitorName;
TCHAR env[12] = TEXT("Windows x64");
m_MonitorInfo2.pEnvironment = env;
m_MonitorInfo2.pDLLName = lpDllName;
if ( !AddMonitor(NULL, 2, (LPBYTE) &m_MonitorInfo2) )
{
DWORD error = GetLastError();
std::cout << "Last error = " << error << "\n";
return PRINTER_ERR_API;
}
When I run this as a member of the Administrators group is fails. GetLastError() returns 5. When I run it as "The Administrator" it succeeds with no issues. I am running on Windows 7 x64. I am trying to install the redmonnt.dll and I do have the 64 bit version of that dll. This task is part of a larger install for a PostScript driver. I've only isolated out the AddMonitor portion to eliminate other external issues.
Error 5 is an access violation or security issue. My first question is why can't a member of the administrators group carry out this function call? What's the difference between the actual administrator and a member of the administrators group given this context?
Other details to note. I am using InstallShield 12 (old) for my Printer installation (addmonitor is only part). I am adding a monitor, port, driver and printer all through win32 function calls. Prior to running my AddPrinterMonitor.exe I made sure that the redmonnt.dll does exist in the system32 directory. Actually, whether the dll is present there or not makes no difference for the error I see. I did see posts about setting SeLoadDriverPrivilege. This is a dead end for me as I checked and the administrators group can Load/Unload device drivers.
Also, I am using win32 calls to get this done. This worked (I mean all of it worked) without any problems on Win2K, WinXP and Windows Server 2003. With the newer OS's like Windows 7 there are several difficulties. Is there a better way that I've overlooked? I been very frustrated trying to get this to work, so I've begun to question the approach for Vista and higher.
More initialization code:
#define MONITOR_NAME "My Redirected Port"
#define MONITOR_FILE "redmonnt.dll"
MONITOR_NAME is passed to lpMonitorName and MONITOR_FILE is passed to lpDllName
thanks

Window7 : run task at boot time and wait for it's completion

How do i run task at boot time and wait for it's completion? I know chkdsk and some other programs are doing that, but how?
Update: i found a way. Native API, if anyone's curious.
Windows have a "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute" key, programs in it are executed before any subsystem is started, i.e. before win32,LSA, etc. The only API avaliable at that time is NativeAPI. Most of it's functions can compromise security and stability of the system (This API can close handles, hide registry keys and more). Of course, a lot of it's functions are undocumented, but guys at http://undocumented.ntinternals.net/ have documented a lot of them.
Here is another method (not sure if this "Native API" is the same but you can use the Windows Task Schedular. There is a On Computer Start on or a User Login option too.
How to install/wrapper (Just for more info): Windows Task Scheduler Installer

Programatically registering .dll's on Windows Vista (using DllRegisterServer)

Instead of calling regsvr32.exe, one can register a .DLL using the following steps:
HINSTANCE hLib = ::LoadLibraryEx(dllPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
HRESULT (STDAPICALLTYPE* lpDllEntryPoint)(void);
(FARPROC&)lpDllEntryPoint = ::GetProcAddress(hLib, "DllRegisterServer");
const HRESULT hRes = (*lpDllEntryPoint)();
This works fine on Windows XP. Regrettably, it fails on Vista, but only with some specific DLLs. hRes becomes E_ACCESSDENIED. I guess this is a security issue. Does anyone know how to register a .DLL from code on Windows Vista?
Note: I was logged in as administrator when running this code.
COM registration requires write access to the HKEY_LOCAL_MACHINE part of the registry.
Under UAC, write access to the HKEY_LOCAL_MACHINE requires an elevated administrator.
The easiest way to get an elevated process is to create it with a manifest that specifies 'requireAdministrator' access. - Look under the Project Properties -> Configuration Properties->Linker->Manifest File->UAC Execution Level to set the correct setting.
This means you will probably want to split your EXE into two parts. The 'normal' asInvoker part, and, when self registration is detected as a requirement, an elevated InstallMyself part. When the non elevated part detects a first-run type condition, it needs to use ShellExecute(Ex) to execute the FirstInstall.exe part - using CreateProcess or some other API will simply fail with a insufficient privilege error. ShellExecute will present the UAC prompt.
It is possible to use Application Isolation to load COM dll's without any registration step at all.
Is is unfortunate that the cause cannot be determined. However, if you are interested in doing further research, a tool that will help a lot would be Process Monitor from SysInternals. Process Monitor can log all the File, Registry and other access for a process, including all success and fail codes making it a lot easier to debug problems like this without having to resort to deeper means of reverse engineering.
Regrettably, I couldn't get this to work for all DLLs, even with Chris Becke's excellent tips. I didn't want to spend too much time solving the problem, so now I simply call regsvr32.exe. I expect this .exe to be present on all Windows machines, so I guess it is a good enough solution.

Resources