Can I launch umdf2 driver using CreateService and StartService APIs in Windows 10? I am looking for any running sample that I could refer.
I have done it with WDM driver previously, but currently I failed to do it with umdf2 driver. Here is the code
WCHAR strPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, strPath);
std::wstring binaryPath(strPath);
binaryPath += L"\\" + pDeviceName + L".dll";
std::string logPath(binaryPath.begin(), binaryPath.end());
cout << "Load Path : " << logPath << endl;
SC_HANDLE hManager, hService;
hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hManager) {
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
cout << "OPenSCManager Access denied - run administration access" << endl;
} else {
cout << "OPenSCManager Error : " << err << endl;
}
return;
}
hService = CreateService(hManager, pDeviceName.c_str(), pDeviceName.c_str(), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, binaryPath.c_str(), NULL, NULL, NULL, NULL, NULL);
if (!hService) {
hService = OpenService(hManager, pDeviceName.c_str(), SERVICE_ALL_ACCESS);
if (!hService) {
CloseServiceHandle(hManager);
return;
}
}
if (!StartService(hService, 0, NULL)) {
DWORD err = GetLastError();
cout << "StartService Error : " << err << endl;
if (err == ERROR_SERVICE_ALREADY_RUNNING) {
cout << "Already running" << endl;
}
}
CloseServiceHandle(hManager);
CloseServiceHandle(hService);
pDeviceName refers to the driver name. Code execution fails with error 2:
StartService Error : 2
I tested this in both Win7 and Win10 and the result is same.
The error code has told us the most of things:
The system cannot find the file specified.
First, check the (pDeviceName).dll is located in Current Directory.
Second, check its dependencies with tools like Dependency Walker, move them to Current Directory or System Directory to make sure the system can also find the dependencies.
Then try to check the "regedit", Open the key HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\pDeviceName, or other similar names. Check the Key value "ImagePath", the path was the first time you have create it. Move dll to the Path or Change the Path to dll.
Related
void main() {
PSID UserSID = NULL;
PSID GroupSID = NULL;
//PSECURITY_DESCRIPTOR *SD = new PSECURITY_DESCRIPTOR;
PSECURITY_DESCRIPTOR SD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR));
PACL pDACL ;
ULONG Count = NULL;
PEXPLICIT_ACCESS_W* pExplicitEntries = new PEXPLICIT_ACCESS_W;
string input, ext = "";
wcout << "Enter the location : " << endl;
std::getline(cin, input);
LPCSTR file = input.c_str();
HANDLE hFile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_ACCESS_DENIED)
{
cout << "Access Denied : System Files" << endl;
return;
}
else if (GetLastError() == ERROR_PATH_NOT_FOUND)
{
cout << "Path Name Not Found" << endl;
return;
}
else if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
cout << "File Not Found" << endl;
return;
}
else
{
cout << GetLastError() << endl;
return;
}
}
cout << GetLastError() << endl;
if ((GetSecurityInfo(hFile,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &SD)) == ERROR_SUCCESS)
{
cout << "Number of ACE : " << pDACL->AceCount << endl;
cout << GetLastError() << endl;
}
for (int i = 0; i < pDACL->AceCount; i++)
{
PACCESS_ALLOWED_ACE AceItem;
ACE_HEADER* AceHdr = NULL;
if (GetAce(pDACL, i, (LPVOID*)&AceItem) && GetAce(pDACL, i, (LPVOID*)&AceHdr))
{
TCHAR AccountBuff[80];
TCHAR DomainBuff[80];
DWORD AccountBufflength = 40;
DWORD DomainBufflength = 40;
PSID_NAME_USE peUse = new SID_NAME_USE;
PSID Sid = &AceItem->SidStart;
LookupAccountSidW(NULL, Sid, AccountBuff, &AccountBufflength, DomainBuff, &DomainBufflength,peUse);
wcout << "\n----- " << AccountBuff << " # " << DomainBuff << " -----\n" << endl;
wcout << "AceType : " << AceHdr->AceType << " " << "Ace Flag : " << AceHdr->AceFlags << "\n" << endl;
DisplayAccessMask(AceItem->Mask);
}
else
{
cout << GetLastError() << endl;
}
}
}`
How to get the correct number of ACE in the security tab of a file property ?
There is only 9 Members in Security Tab of File Property but the Access Control List consist of 13 ACE.
Can anyone tell me how can i get the users listed in the security tab ->advanced and their file permission...
An ACE contains a set of access rights and a security identifier (SID)
that identifies a trustee for whom the rights are allowed, denied, or
audited.
ACE is access control entry, it not one-to-one correspondent to users and groups.
Each ACE in an access control list (ACL) applies to one trustee. But for one trustee, there may be multiple ACEs, like below, the same Administrators group has two ACEs, one is type of deny and another is type of allow:
Can anyone tell me how can i get the users listed in the security tab
->advanced and their file permission...
GetSecurityInfo does give me consistent number to permission entries at file properties -> secutiry -> advanced.
Update:
Number Of ACE of a File - There is only 9 Members in Security Tab of
File Property but it returns 13 ACE from ACL
It may happen that you find there is a difference between ACEs entries number (returned returned by GetSecurityInfo() and GetAce()) and the permission entries number (in the advanced security tab for folders).
Take folder C:/program files as an example. There are 9 permissions entries show in the advanced security tab for this folder as below.
However you may get 13 ACE entries using GetSecurityInfo() and GetAce().
It is expected because there is no 1:1 mapping between the ACE entry and the permission entry in the dialog.
File explorer applies some rules in order for displaying permission entries friendly to users. For example, there are two ACE entries, one is the full control for this folder and another is full control for subfolders, both of them for same user: TrustedInstaller. These two ACEs are merged into one displayed.
Trying to retrieve the running directory of a process using the PID. I am obtaining the PID using FindWindow() and GetWindowThreadProcessId() which results in the same process ID as shown in task manager, so I assume it to be correct.
When using GetModuleFileNameEx(), instead of resulting in a path, I get what seems to be a memory address.
auto wnd = FindWindow(nullptr, L"prog");
while (wnd == nullptr)
{
wnd = FindWindow(nullptr, L"prog");
}
TCHAR fBuf[MAX_PATH]; // buffer for path
DWORD procId; // process id
GetWindowThreadProcessId(wnd, &procId); // get process id
std::cout << procId << std::endl; // results in correct pid
auto procHdl = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, procId); // create handle for process
if (procHdl != NULL) {
if (GetModuleFileNameEx(procHdl, 0, fBuf, MAX_PATH) == 0) {
std::cerr << "Failed to get module filename." << std::endl;
}
else {
std::cout << "Module filename is: " << fBuf << std::endl;
}
CloseHandle(procHdl);
}
Sample output is:
10488
Module filename is: 008CF93C
I have had the same result using GetProcessImageFileNname() too.
To get the directory of a program, first use GetModuleFileNameEx to get the program path, and your directory will start from the first character to the last backslash found.
Example:
Program is: "C:\Windows\notepad.exe";
Directory is: "C:\Windows";
In code:
DWORD pid = 104;
CHAR ProgramFile[MAX_PATH];
std::string DirectoryPath;
HANDLE hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, pid);
GetModuleFileNameExA(hProcess, NULL, ProgramFile, MAX_PATH);
DirectoryPath = ProgramFile;
DirectoryPath = DirectoryPath.substr(0, DirectoryPath.find_last_of('\\'));
std::cout << "ProgramFile: " << ProgramFile << endl;
std::cout << "Directory: " << DirectoryPath.c_str();
Trying to convert the network drive or mapped drive(Z:) to its UNC path( 192.168.x.x\Shared). Tried different ways like WNetGetUniversalName and WNetGetConnection, but getting error like ERROR_NOT_CONNECTED or ERROR_CONNECTION_UNAVAIL. then elevated its privileges and also tried with api LogonUser. but still getting same errors.
Then tried using WMI query, it works fine when running in console mode. But it is not working in service mode. Even Function to convert UNC path from the network drive is not directly called under service running process. Suppose Service process name is "parentService.exe", it creates a child called "childService.exe". this "childService.exe" is running function of converting network drive to UNC path, this means "childService.exe" is actually a console application running without standard I/O's.
this same "childService.exe" works fine if its run as individually in console mode. variable "vRet.bstrVal"(provider name) contains unc path. it doesn't give any error for service mode running, it just returns successfully .but while loop condition is not met. Both console and service runs on same user.
How to make it work also when it runs as part of service?
Here is code the for it:
#include <windows.h>
#include <Winnetwk.h>
#include <iostream>
#pragma comment(lib, "wbemuuid.lib")
int wmi_call()
{
HRESULT hRes;
hRes = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hRes))
{
cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
return 1;
}
if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
{
cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
return 1;
}
IWbemLocator* pLocator = NULL;
if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
{
cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
return 1;
}
IWbemServices* pService = NULL;
if (FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
{
pLocator->Release();
cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
return 1;
}
IEnumWbemClassObject* pEnumerator = NULL;
if (FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT ProviderName FROM Win32_LogicalDisk where DeviceId = \"Z:\"", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
{
pLocator->Release();
pService->Release();
cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
return 1;
}
IWbemClassObject* clsObj = NULL;
int numElems;
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
{
if (FAILED(hRes))
break;
VARIANT vRet;
VariantInit(&vRet);
hRes = clsObj->Get(L"ProviderName", 0, &vRet, NULL, NULL);
if (SUCCEEDED(hRes) && vRet.vt == VT_BSTR)
{
std::wcout << L"Succesfull conversion to UNC path, ProviderName: " << vRet.bstrVal << endl;
VariantClear(&vRet);
}
else
{
cout << "Unable clsObj " << std::hex << hRes << endl;
}
clsObj->Release();
}
pEnumerator->Release();
pService->Release();
pLocator->Release();
return 0;
}
it worked fine, when used "SELECT ProviderName FROM Win32_MappedLogicalDisk where DeviceId = \"Z:\"" instead of
"SELECT ProviderName FROM Win32_LogicalDisk where DeviceId = \"Z:\""
Our team need to develop an app runing at IoT Non-UWP environment, and we need to call the sensor COM interface. but it failed at first to use the CoCreateInstanceFromApp/CoCreateInstanceEx.
The code snippet is like this:
ULONG ulCount = 0;
COINIT dwCoinit = COINIT_MULTITHREADED;
auto hr2 = CoInitializeEx(NULL, dwCoinit);
if (FAILED(hr2))
{
cout << "Failed to run CoInitializeEx: " << hr2 << endl;
return;
}
MULTI_QI res = { 0 };
res.pItf = NULL;
res.hr = S_OK;
res.pIID = &IID_PPV_ARGS(&_pSensor);
//_hr = CoCreateInstanceEx(CLSID_SensorManager,
_hr = CoCreateInstanceFromApp(CLSID_SensorManager,
NULL, CLSCTX_INPROC_SERVER, NULL, 1, &res);
if (S_OK != _hr)
{
auto result = GetLastError();
cout << "Failed Create Instance : " << _hr << " WinAPI Error: " << result <<endl;
return;
}
and it failed with the log:
Failed Create Instance : -2147221164 WinAPI Error: 1008
the error code means:
(-2147221164) “Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))”
1008 means: ERROR_NO_TOKEN
it seems the sensorManager is not available.
Anyone know the method to fix it, and does MSFT expose the sensor api for Non-UWP environment?
Thanks
Jerome
I am trying to load an ISO file in my program and mount it by using the Windows 8.1 Virtual Disk service. Before I load the ISO I load a VHD file on which a game resides. then I want to mount the ISO for the game to work (the ISO resides on the VHD but the problem also occurs when the ISO resides within the program directory).
Now, I don't know why the operation is "NOT SUPPORTED" (error code 50), but I know that windows is able to mount ISO's because when I double click them, they get mounted by windows Explorer (and it obviously uses the Virtual Disk Service, as the KB of the virtual service states that ISO mounting is supported from windows 7 and later).
Now, how I try to load the iso file is this:
GUID GUID_TEST = { 12345678 - 1234 - 5678 - 1234 - 000000000000 };
//convert string to wstring
std::wstring s2ws(const std::string& str)
{
typedef std::codecvt_utf8<wchar_t> convert_typeX;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.from_bytes(str);
}
DWORD OpenISO(const char* isoFilePath, HANDLE *handle)
{
VIRTUAL_STORAGE_TYPE storageType =
{
VIRTUAL_STORAGE_TYPE_DEVICE_ISO,
GUID_TEST
};
OPEN_VIRTUAL_DISK_PARAMETERS parameters =
{
OPEN_VIRTUAL_DISK_VERSION_1
};
return ::OpenVirtualDisk(
&storageType,
s2ws(std::string(isoFilePath)).c_str(),
VIRTUAL_DISK_ACCESS_READ,
OPEN_VIRTUAL_DISK_FLAG_NONE,
¶meters,
handle);
}
void main()
{
//load VHD here, do some program setup, etc etc
//then load iso:
//makesure VHD is mounted and ready
UINT dtype = GetDriveTypeA(Config.MountPoint.c_str());
while (dtype == 1 || dtype == 0)
{
dtype = GetDriveTypeA(Config.MountPoint.c_str());
Sleep(10);
}
std::cout << "OK" << std::endl;
//just a bit more waiting to be sure it is really loaded correctly
Sleep(2500);
//now load the iso our game needs to run
HANDLE isohandle;
if (FileExists(Config.ISO_location.c_str()))
{
std::cout << "Mounting ISO... " << std::flush;
if (OpenISO(Config.ISO_location.c_str(), &isohandle) == ERROR_SUCCESS)
{
if (AttachVirtualDisk(isohandle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, 0, 0, NULL) == ERROR_SUCCESS)
{
std::cout << "ISO mounted.\r\n";
}
else
{
std::cout << "ISO NOT mounted (" << GetLastError() << ").\r\n";
}
}
else
{
std::cout << "Cannot open ISO file, skipping (" << GetLastError() << ").\r\n";
}
}
//launch the game process here
//wait til game ends
//cleanup
//shutdown
}
I always get the message ISO NOT mounted(50). When replacing GUID_TEST with the microsoft default guid I get ISO NOT mounted(0), Error code 0 should indicate succes, but somehow the ISO does not appear in disk management. What is wrong here? Why won't my ISO be mounted programaticly while explorer can?
I admit I don't exactly know how to mount an ISO, but I do mount a VHD this way:
DWORD OpenVDisk(const char* virtualDiskFilePath, HANDLE *handle)
{
VIRTUAL_STORAGE_TYPE storageType =
{
VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT
};
OPEN_VIRTUAL_DISK_PARAMETERS parameters =
{
OPEN_VIRTUAL_DISK_VERSION_1
};
parameters.Version1.RWDepth = 1024;
return ::OpenVirtualDisk(
&storageType,
s2ws(std::string(virtualDiskFilePath)).c_str(),
VIRTUAL_DISK_ACCESS_ALL,
OPEN_VIRTUAL_DISK_FLAG_NONE,
¶meters,
handle);
}
//somewhere else
HANDLE handle;
DWORD result;
ULONG bytesUsed;
result = OpenVDisk(Config.VHD_location.c_str(), &handle);
if (result != ERROR_SUCCESS)
{
std::cout << "Unable to open virtual disk '" << Config.VHD_location << "'" << std::endl;
return (int)pressanykey("Hit any key to quit the application\r\n");
}
std::cout << "OK" << std::endl;
std::cout << "Attaching Game Disk..." << std::flush;
result = AttachVirtualDisk(handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, 0, NULL);
if (result != ERROR_SUCCESS)
{
std::cout << "Unable to attach virtual disk (did you forget to run this program with administrative rights? -- " << GetLastError() << ")" << std::endl;
return (int)pressanykey("Hit any key to quit the application\r\n");
}
std::cout << "OK" << std::endl;
and the VHD mounting works. This makes me really wonder why ISO does not.
The solution is to make sure the ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME flag is specified, then also make sure the ISO file size is a multiple of 2048 bytes. Now it works.