question

Hari-5839 avatar image
0 Votes"
Hari-5839 asked DoronHolan commented

CreateFile / CreatefileA getlasterror returns 5

I am trying to access a device in the device manager. (The device exposes some functionality, only after getting the handle I could perform IOCTL calls)

from the C++ app, I was able to get device details with the help of GUID.

I am getting the device path from SetupDiGetDeviceInterfaceDetail(). but with the device path, when I try to open using createfile / createFileA I am getting error code as 5, which is access denied.

I am in admin mode only. Below is the sample code.

 #pragma comment(lib,"Setupapi.lib")
    
    
 #ifdef __cplusplus
 extern "C" {
 #endif
    
 #include <windows.h>
 #include <tchar.h>
    
 #include <setupapi.h>
 #include <initguid.h>
    
 #include <stdio.h>
    
    
 class __declspec(uuid("{XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}")) guid;
 GUID W_GUID = __uuidof(guid);
    
 int main()
 {
 HDEVINFO                         hDevInfo;
 SP_DEVICE_INTERFACE_DATA         DevIntfData;
 PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
 SP_DEVINFO_DATA                  DevData;
    
    
 hDevInfo = SetupDiGetClassDevs(
 &W_GUID, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    
 if (hDevInfo != INVALID_HANDLE_VALUE)
 {
 DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 dwMemberIdx = 0;
    
 bool result = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &W_GUID ,
 dwMemberIdx, &DevIntfData);
    
 DevData.cbSize = sizeof(DevData);
    
 SetupDiGetDeviceInterfaceDetail(
 hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
    
 DevIntfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
 DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
 SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData,
 DevIntfDetailData, dwSize, &dwSize, &DevData);
    
    
 HANDLE _hDevice = CreateFile((LPCWSTR)DevIntfDetailData->DevicePath,
 GENERIC_READ | GENERIC_WRITE,
 FILE_SHARE_READ | FILE_SHARE_WRITE,
 NULL,
 OPEN_EXISTING,
 FILE_FLAG_OVERLAPPED,
 NULL);
    
 if (_hDevice == INVALID_HANDLE_VALUE)
 {
 int err = GetLastError();
 if (err != 0)
 {
 std::cout << "error";
 }
 std::cout << _hDevice;
 std::cout << "Error ";
 }
 SetupDiDestroyDeviceInfoList(_hDevice);
 }
 }
 }
windows-api
· 15
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Do you need GENERIC_WRITE in the call to CreateFile?

Anything about using IOCTLs for the device in related documentation?

0 Votes 0 ·

GENERIC_WRITE is not required, but since I was getting invalid handle, tried all combinations.
device documentation I have only guid and set of IOCTLs CTL codes.

0 Votes 0 ·

Try passing 0 instead of GENERIC_WRITE | GENERIC_READ. Also, try removing FILE_FLAG_OVERLAPPED.

0 Votes 0 ·
Show more comments

1 Answer

RLWA32-6355 avatar image
2 Votes"
RLWA32-6355 answered RLWA32-6355 commented

So it would appear that the security descriptor for your device only permits access to the SYSTEM account.
You can test this by using PsExec to open a command prompt window that is running under the SYSTEM account. In that command prompt window run your application.

To accomplish this -
1. Install PsExec
2. Open a command prompt window with elevated privileges that is running as an Administrator.
3. In the elevated command prompt run the command "psexec -s -i -d cmd"
4. A new command prompt window will open that is running as SYSTEM. You can confirm with the whoami command.
5. In the SYSTEM command prompt window run your application.



· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Yes.. i am able to get the createfile handle now.. this is good. thanks a lot.. :)

do we have any other way other than running from PsExec tool?

0 Votes 0 ·

Another possibility for you to consider is to modify the security descriptor for your device to permit administrator access.

1 Vote 1 ·

Another way is to use a scheduled task. When creating the task you can configure it to run using the SYSTEM account. However, the process will be created in session 0 which is a non-interactive session so no user interface will be visible. So any output that you want to see should be written to a file instead.

Other possibilities depend upon writing code to use your administrator privileges to "steal" a token from a process that is running as SYSTEM. A common target for such token theft is the winlogon.exe process. Once you have obtained a handle to such a token you can use it for impersonation or to start a new process with CreateProcessAsUser. But these things are beyond the scope of this question.

0 Votes 0 ·

ok got it.
I will do few experiments and will figure out..

Thanks for the help and it was nice working with you @RLWA32-6355.

0 Votes 0 ·