How To call DeviceIoControl with 32 bit app 3264 bit driver

Hi,

I am a novice C++ programmer.

I have to modify already working code of someone else to include 64 bit DeviceIoControl calls as well as 32 bit calls.

Entire 32 bit app and driver works just fine on 32 bit windows:

HANDLE hDev = CreateFile(L"\\.\wikdr",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);

DeviceIoControl(hDev,
IOCTL_GET_PATH,
(LPVOID)(LPCTSTR)m_FileName,
(DWORD)m_FileName.GetLength()*sizeof(WCHAR),
Buffer,
BufferSize,
BytesReturned,
NULL)

On 64 bit vista however it returns 6 ERROR_INVALID_HANDLE from the driver at the last call.

I have been reading on the subject for the past 3 days. But it is beyond me. Can anybody please fix this code for me so that it will work with both 32 and 64 bit drivers.

Same 32 bit driver has been compiled to x64 ,signed, installed and properly running. Just need a way to communicate with it.

I have the code to the driver too, but cannot change it. Because I have no longer can sign 64 bit drivers. So, fix has to be on the 32 bit app side. hdev is a 32 bit address, because app is 32 bit and kernel expects 64.

P.S:
While debugging the app Createfile does not fail hdev returns an 32 bit address like 0x00004724 and err watch only changes after DeviceIoControl is called. 64 bit driver expects a 64 bit address not 32. This could be the cause. Not sure how to implement that though on the 32 bit app side for both 32 and 64 bit drivers, Also, other parameters of that function might need casting or extending. Not sure how to properly code that.

Please keep it real simple, if you can.

.

xxxxx@instantlock.net wrote:

I am a novice C++ programmer.

I have to modify already working code of someone else to include 64 bit DeviceIoControl calls as well as 32 bit calls.

Entire 32 bit app and driver works just fine on 32 bit windows:

HANDLE hDev = CreateFile(L"\\.\wikdr",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);

DeviceIoControl(hDev,
IOCTL_GET_PATH,
(LPVOID)(LPCTSTR)m_FileName,
(DWORD)m_FileName.GetLength()*sizeof(WCHAR),
Buffer,
BufferSize,
BytesReturned,
NULL)

On 64 bit vista however it returns 6 ERROR_INVALID_HANDLE from the driver at the last call.

I have been reading on the subject for the past 3 days. But it is beyond me. Can anybody please fix this code for me so that it will work with both 32 and 64 bit drivers.

There is nothing here that should need any changes at all. Are you
quite sure that your driver registers the “wikdr” symbolic link when
compiled for 64 bits?

I have the code to the driver too, but cannot change it. Because I have no longer can sign 64 bit drivers. So, fix has to be on the 32 bit app side. hdev is a 32 bit address, because app is 32 bit and kernel expects 64.

Nope. hdev is a 32-bit address because your process is 32-bit. The
operating system handles the mapping from a 32-bit file handle to the
appropriate kernel driver.

While debugging the app Createfile does not fail hdev returns an 32 bit address like 0x00004724 and err watch only changes after DeviceIoControl is called. 64 bit driver expects a 64 bit address not 32. This could be the cause. Not sure how to implement that though on the 32 bit app side for both 32 and 64 bit drivers, Also, other parameters of that function might need casting or extending. Not sure how to properly code that.

Exactly how is IOCTL_GET_PATH defined? I assume it is
METHOD_OUT_DIRECT. If so, in this particular case, you are not passing
any addresses. Thus, the operating system will do the necessary mapping
to make sure that the driver gets 64-bit addresses. If IOCTL_GET_PATH
is foolishly defined as METHOD_NEITHER, then you do have a problem, and
it’s one you cannot solve in the application.

Does your driver code do any validation of the parameters in the
IOCTL_GET__PATH call?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

“On 64 bit vista however it returns 6 ERROR_INVALID_HANDLE from the driver at the last call.”

If you’re passing an invalid handle to DeviceIOControl then the CreateFile call failed.

Call GetLastError() after CreateFile and you’ll be closer to finding the problem.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@instantlock.net
Sent: Friday, June 26, 2015 11:44 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] How To call DeviceIoControl with 32 bit app 3264 bit driver

Hi,

I am a novice C++ programmer.

I have to modify already working code of someone else to include 64 bit DeviceIoControl calls as well as 32 bit calls.

Entire 32 bit app and driver works just fine on 32 bit windows:

HANDLE hDev = CreateFile(L"\\.\wikdr",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);

DeviceIoControl(hDev,
IOCTL_GET_PATH,
(LPVOID)(LPCTSTR)m_FileName,
(DWORD)m_FileName.GetLength()*sizeof(WCHAR),
Buffer,
BufferSize,
BytesReturned,
NULL)

On 64 bit vista however it returns 6 ERROR_INVALID_HANDLE from the driver at the last call.

I have been reading on the subject for the past 3 days. But it is beyond me. Can anybody please fix this code for me so that it will work with both 32 and 64 bit drivers.

Same 32 bit driver has been compiled to x64 ,signed, installed and properly running. Just need a way to communicate with it.

I have the code to the driver too, but cannot change it. Because I have no longer can sign 64 bit drivers. So, fix has to be on the 32 bit app side. hdev is a 32 bit address, because app is 32 bit and kernel expects 64.

P.S:
While debugging the app Createfile does not fail hdev returns an 32 bit address like 0x00004724 and err watch only changes after DeviceIoControl is called. 64 bit driver expects a 64 bit address not 32. This could be the cause. Not sure how to implement that though on the 32 bit app side for both 32 and 64 bit drivers, Also, other parameters of that function might need casting or extending. Not sure how to properly code that.

Please keep it real simple, if you can.

.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hi Tim,
Thank you for the reply. I tried to answer your questions I hope it helps:

Are you quite sure that your driver registers the “wikdr” symbolic link when
compiled for 64 bits?
Well, it is shown as installed and running on Process Hacker services tab as a FS Driver with that same name. Otherwise createfile would return -1 wouldn’t it?

Exactly how is IOCTL_GET_PATH defined?
#define IOCTL_GET_PATH \
CTL_CODE(0x1000, 0x100, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS)

Does your driver code do any validation of the parameters in the
IOCTL_GET__PATH call?
Yes. It does check output buffer size etc. But if check fails it returns some other error not error 6

I thought Windows did thunking for other data types but not handles. If it does convert it automatically as you explained why would it return error 6, I don’t get it. I don’t know how to implement it properly I was thinking something like :

if (_64bit) {
// DeviceIoControl64bit with 64 bit extended variables
//…

}
else
{
// DeviceIoControl as usual
//…

};

@Jonathan

Call GetLastError() after CreateFile and you’ll be closer to finding the
problem.

Like I said on the original P.S.

While debugging the app Createfile does not fail hdev returns an 32 bit address
like 0x00004724 and err watch only changes after DeviceIoControl is called

I am debugging with a whatch err, and it only changes from 0 to 6 AFTER deviceiocontrol called
Do I still need to use GetLastError() when there is a err watch like I said?

Using Windbg was easier than I thought after a few hours, it turns out 64 bit kernel driver is to blame… Silly me… Duh !

A-How would you fix this.

B-Since my individual kernel signing certificate expired and it was a pain to get one the first time and they no longer even sell them.
Can anybody PLEASE re-sign the modified 64 bit sys file? I could provide the signed driver too.

//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------

status = ZwDuplicateObject(hProcess,(HANDLE)SysHandle[i].Handle,ZwCurrentProcess(),&ObjectHandle,0, 0, DUPLICATE_SAME_ATTRIBUTES |DUPLICATE_SAME_ACCESS);
DbgPrint(“status:%d sourceProcess:%p SourceHandle:%d CurrentProcess:%d returnedObjectHandle:%d.\n”, RtlNtStatusToDosError(status),hProcess, (HANDLE)SysHandle[i].Handle,PsGetCurrentProcessId(),&ObjectHandle);

//On_32bit status:0 sourceProcess:80002CB8 SourceHandle:68 CurrentProcess:3984 returnedObjectHandle:-340903132.
//On_64bit status:0 sourceProcess:FFFFFFFF800001BC SourceHandle108 CurrentProcess:1996 returnedObjectHandle:221378472.

status = ObReferenceObjectByHandle(ObjectHandle, FILE_ANY_ACCESS, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, &objHandle);
DbgPrint(“status %d.\n”, RtlNtStatusToDosError(status));
//On_64bit status=STATUS_INVALID_HANDLE (error 6 here only on 64 bit on 32 it is 0 as expected) !!!???

//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------

Why do you need to do that with the file object? By the way, your ObReferenceObjectByHandle is opening you to the security hole.

Hi osronline community,

This driver is part of a free app like OpenedFilesView from Nirsoft. It already works much better than Nirsoft app on 32 bit systems.

1-This is just the problematic part of a function that searches handles of open files on a given path. I added dbgprint after each line to monitor ntstatus object to compare output with 32 bit driver.It only differs at these lines. It does not mean there is not a hidden error above like a new Vista 64 bit feature like anti hook etc… I have no idea, that is why I am asking to more experienced users.

2-Is there a good video tutorial to setup vmware with vs 2008 to debug kernel drivers?

3-Can anybody actually fix this function if I create a stripped down driver+app and send it via e-mail to someone with only this one problematic function?

4-I tried many combinations of that last function but the original code does not use kernelmode. I tried many parameter options same result error 6 risgt after this function but only on 64 bit systems. The original line is this.

status = ObReferenceObjectByHandle(ObjectHandle, FILE_ANY_ACCESS,
*IoFileObjectType, UserMode, (PVOID*)&FileObject, NULL);

//On_32bit status:0 sourceProcess:80002CB8 SourceHandle:68 CurrentProcess:3984
returnedObjectHandle:-340903132.
//On_64bit status:0 sourceProcess:FFFFFFFF800001BC SourceHandle108
CurrentProcess:1996 returnedObjectHandle:221378472

Any solutions? ANYBODY?

From 32/64 compat point of view, handle is a pointer.

In your 64bit code, just zero-extend the 32bit handles from the 32bit world, to make them valid 64bit handles for 64bit world.

The proper field data type for the handle in 32/64 compat IOCTL structures is ULONG_PTR


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hi osronline community,
>
> This driver is part of a free app like OpenedFilesView from Nirsoft. It already works much better than Nirsoft app on 32 bit systems.
>
> 1-This is just the problematic part of a function that searches handles of open files on a given path. I added dbgprint after each line to monitor ntstatus object to compare output with 32 bit driver.It only differs at these lines. It does not mean there is not a hidden error above like a new Vista 64 bit feature like anti hook etc… I have no idea, that is why I am asking to more experienced users.
>
> 2-Is there a good video tutorial to setup vmware with vs 2008 to debug kernel drivers?
>
> 3-Can anybody actually fix this function if I create a stripped down driver+app and send it via e-mail to someone with only this one problematic function?
>
> 4-I tried many combinations of that last function but the original code does not use kernelmode. I tried many parameter options same result error 6 risgt after this function but only on 64 bit systems. The original line is this.
>
> status = ObReferenceObjectByHandle(ObjectHandle, FILE_ANY_ACCESS,
> IoFileObjectType, UserMode, (PVOID)&FileObject, NULL);
>
> //On_32bit status:0 sourceProcess:80002CB8 SourceHandle:68 CurrentProcess:3984
> returnedObjectHandle:-340903132.
> //On_64bit status:0 sourceProcess:FFFFFFFF800001BC SourceHandle108
> CurrentProcess:1996 returnedObjectHandle:221378472
>
> Any solutions? ANYBODY?
>
> …
>