DeviceIOControl() failing with error 50! HELP please.

Hi

I’m very new to communication with Windows Device Drivers. :slight_smile:

I’m new to the forum too, I will be helpful if someone help me.

A) I need to communicate with a third-party driver. I see that CreateFile() accept both the device name (such as \.\DeviceName) and also I can call the full file name (such as \.\C:\MyPath\DriverName.sys). What is the best option? Why? Both works on the same way?

B) I see that many device drivers has two names, for example:

SymbolicLink “\GLOBAL??\VirtualSerial” Destination “\Device\VrSerialrs232”

If I try open for example open VrSerialrs232 with CreateFile() it fails. So, why is used the VrSerialrs232 if I always have to call the SymbolicLink (VirtualSerial)?

C) I installed a DeviceIOControl monitor to check why my code is failing with Error 50 (The request is not supported) and I can’t figure why.

The output of the DeviceIOControl monitor is here: http://img254.imageshack.us/img254/5439/picggi.png

The ones from test.exe are my code, the other (protected) is the original application calling the same device.

My code is like this:

#include “stdafx.h”
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>

void ErrorExit(LPTSTR lpszFunction){
// Retrieve the system error message for the last-error code

LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

// Display the error message and exit the process

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT(“%s failed with error %d: %s”),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT(“Error”), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}

BOOL OpenDevice(PWSTR DriverName, HANDLE lphDevice){

WCHAR DeviceName[MAX_PATH]; HANDLE hDevice;

if ((GetVersion() & 0xFF) >= 5) {
wcscpy(DeviceName, L"\\.\Global\“);
} else {

wcscpy(DeviceName, L”\\.\"); }
wcscat(DeviceName, DriverName); printf(“Opening… %S\n”, DeviceName);
hDevice = CreateFileW(DeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hDevice == INVALID_HANDLE_VALUE) {
printf(“CreateFile() ERROR %d\n”, GetLastError()); return FALSE;

}

lphDevice = hDevice; return TRUE;
}

int _tmain(int argc, _TCHAR
argv[]){

HANDLE hDevice = NULL;
DWORD cb = 0;
int ret = 0;
char tcode[] = “\x8a\xb3\x39\x9d”; /
Copied from original request seen on Monitor) */

if(!OpenDevice(L"MyDeviceName",&hDevice)) {

printf(“Error: Error opening device\n”);
return(0);
} else {

printf(“Device succesfully opened!\n”);

}

char *Buff = (char *)VirtualAlloc(NULL, 0x330, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if (Buff){

ret = DeviceIoControl(hDevice, 0xa028442f, tcode, 0x04, 0, NULL, &cb, (LPOVERLAPPED)NULL);

if (ret == 0) {
printf(“Error: Bytes returned %#x\n”,cb);
ErrorExit(TEXT("DeviceIoControl: "));
}

}

CloseHandle(hDevice);
return(0);
}

I always get this error:

C:>Test.exe Opening… .\Global\MyDeviceName Device succesfully opened! Error: Bytes returned 0 DeviceIOControl: Error 50 - The request is not supported

Why?

Thanks</strsafe.h></stdio.h></windows.h>

xxxxx@googlemail.com wrote:

I’m very new to communication with Windows Device Drivers. :slight_smile:

I’m new to the forum too, I will be helpful if someone help me.

A) I need to communicate with a third-party driver. I see that CreateFile() accept both the device name (such as \.\DeviceName) and also I can call the full file name (such as \.\C:\MyPath\DriverName.sys). What is the best option? Why? Both works on the same way?

Those are two VERY different operations, and I would hope that you could
see the difference. The second one opens the driver’s binary as a
regular file. You can read the bytes, but that’s not useful. It’s like
doing a Create file on “notepad.exe”. Possible, but not useful.

The first one opens a handle into the running driver, allowing you to
send requests to that driver.

B) I see that many device drivers has two names, for example:

SymbolicLink “\GLOBAL??\VirtualSerial” Destination “\Device\VrSerialrs232”

If I try open for example open VrSerialrs232 with CreateFile() it fails. So, why is used the VrSerialrs232 if I always have to call the SymbolicLink (VirtualSerial)?

The \Device name is a name in the kernel namespace. That namespace is
not exposed to user-mode. The first name is in the set of names exposed
to user mode. Some drivers offer services only to other kernel devices.

C) I installed a DeviceIOControl monitor to check why my code is failing with Error 50 (The request is not supported) and I can’t figure why.

The output of the DeviceIOControl monitor is here: http://img254.imageshack.us/img254/5439/picggi.png

The ones from test.exe are my code, the other (protected) is the original application calling the same device.

Where did you get the ioctl code from? 0xa028442f is not a typical
ioctl code. It’s not impossible, but it’s very unusual, and that makes
it suspicious. That looks more like a kernel address.

What kind of a driver is this? Some particularly paranoid drivers will
only service certain applications.


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

Hi Tim

Thanks a lot for your reply, very appreciated. :slight_smile:

A) Ohh great, it makes a lot of sense. I was suspecting of it, but I got unsure since I did read a few posts talking about opening the device drive, maybe it was my interpretation that was wrong.

B) Interesting, make sense too. So, all SymbolicLink to a device driver should be accessible from user-mode? I’m asking because to learn I listed all my device drivers and I see one device driver that has the SymbolicLink and the \Device name, but it always fail when I try open it via the SymbolicLink or \Device name. Maybe it’s a protection like the one you mentioned before?

C) I got this 0xa028442f from a tool that monitor all IOCTL calls, and I pasted the code with this IOCTL code, but I also tested with the IOCTL code as seen on the screenshot on my previous post, see:

ret = DeviceIoControl(hDevice, 0x86DB3F68, tcode, 0x04, 0, NULL, &cb, (LPOVERLAPPED)NULL);

But I still get the same error.

It may be a kernel address since it used METHOD_NEITHER, right?

Anyway, even if it’s a kernel address, the worst that should happen is a BSOD, right? But nothing happens, and I only get this error code 50.

Below is a example of the IOCTL monitor that I used to replicate a exactly call made by the original program that works:

Log started…
‘C:\PathToApplication\OriginalAppName.exe’ (PID: 2896)
‘\Device\VSFilterbpd’ (0x86b83c40) [??\C:\LocalPath\DeviceDriverName.sys]
SymbolicLink “\GLOBAL??\VSFFilter”
IOCTL Code: 0xa028442f, Method: METHOD_NEITHER

InBuff: 0x004883a4, InSize: 0x00000004

9c 84 e2 86 | …

OutBuff: 0x004b4f68, OutSize: 0x00001b20

03 00 00 00 1c 03 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 e4 0c 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 0e 00 00 00 ff 01 0f 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 90 85 41 00 | …A.
00 00 00 00 43 00 3a 00 5c 00 69 00 6f 00 63 00 | …C.:..i.o.c.
74 00 6c 00 73 00 2e 00 74 00 78 00 74 00 00 00 | t.l.s…t.x.t…
01 05 00 00 00 00 00 05 15 00 00 00 04 16 d0 48 | …H
4d 16 6d 7a f8 80 b7 61 f4 01 00 00 00 00 00 00 | M.mz…a…
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …

This driver is a File System driver, nothing very special (at least I think).

Any idea why it may be failing yet? Maybe I did it wrong? Or missed some point from the monitor output?

Thanks.

Best regards

xxxxx@googlemail.com wrote:

B) Interesting, make sense too. So, all SymbolicLink to a device driver should be accessible from user-mode? I’m asking because to learn I listed all my device drivers and I see one device driver that has the SymbolicLink and the \Device name, but it always fail when I try open it via the SymbolicLink or \Device name. Maybe it’s a protection like the one you mentioned before?

Symbolic links can be used to create (nearly) arbitrary names in the
kernel namespace. The only names which can be used from user mode with
CreateFile are the names within the \DosDevices namespace. In user
space, \. is mapped to \DosDevices. So, a symbolic link declared as
“\DosDevices\MyDriver” can be opened from user mode as “\\.\MyDriver”

In virtually every case, that’s what you’ll see symbolic links used for
in drivers.

C) I got this 0xa028442f from a tool that monitor all IOCTL calls, and I pasted the code with this IOCTL code, but I also tested with the IOCTL code as seen on the screenshot on my previous post, see:

ret = DeviceIoControl(hDevice, 0x86DB3F68, tcode, 0x04, 0, NULL, &cb, (LPOVERLAPPED)NULL);

But I still get the same error.

86DB3F68 is also likely to be a kernel address rather than an ioctl
code. If you can attach a debugger to the application you’re reverse
engineering, you can set a breakpoint on DeviceIoControl and see what
the real parameters are.

It may be a kernel address since it used METHOD_NEITHER, right?

Your first one (A028442F) would be METHOD_NEITHER. This one (86DB3F68)
would be METHOD_BUFFERED, but I doubt that’s what it is.

Anyway, even if it’s a kernel address, the worst that should happen is a BSOD, right? But nothing happens, and I only get this error code 50.

No. Each driver contains a switch statement on the ioctl codes it
supports. If it gets one it does not support, it returns
STATUS_NOT_SUPPORTED, which gets converted to ERROR_NOT_SUPPORTED, which
is what you see.

Below is a example of the IOCTL monitor that I used to replicate a exactly call made by the original program that works:

Log started…
‘C:\PathToApplication\OriginalAppName.exe’ (PID: 2896)
‘\Device\VSFilterbpd’ (0x86b83c40) [??\C:\LocalPath\DeviceDriverName.sys]
SymbolicLink “\GLOBAL??\VSFFilter”
IOCTL Code: 0xa028442f, Method: METHOD_NEITHER

InBuff: 0x004883a4, InSize: 0x00000004

9c 84 e2 86 | …

OutBuff: 0x004b4f68, OutSize: 0x00001b20

Note that this call has both an input buffer and an output buffer. You
are not providing an output buffer.

As I said, depending on the driver type, it’s quite possible the driver
has some kind of security check built in, so that it can only be used by
certain applications.

This driver is a File System driver, nothing very special (at least I think).

File system drivers are usually not addressed by opening a handle
directly and sending ioctls. Instead, you open a file that resides on
the disk subsystem that it supports.

What are you really trying to do here?


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

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@googlemail.com
Sent: Friday, October 15, 2010 1:14 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] DeviceIOControl() failing with error 50! HELP please.

Hi

I’m very new to communication with Windows Device Drivers. :slight_smile:

I’m new to the forum too, I will be helpful if someone help me.

A) I need to communicate with a third-party driver. I see that CreateFile()
accept both the device name (such as \.\DeviceName) and also I can call the
full file name (such as \.\C:\MyPath\DriverName.sys). What is the best
option? Why? Both works on the same way?

In one case, you are opening the device which the driver implements, which
causes the code in your driver to be called.

In the other case, you are opening the .sys file, which contains the code of
the driver. It is not clear what value this could possibly have, because it
is just a random file at that point.

B) I see that many device drivers has two names, for example:

SymbolicLink “\GLOBAL??\VirtualSerial” Destination “\Device\VrSerialrs232”

If I try open for example open VrSerialrs232 with CreateFile() it fails. So,
why is used the VrSerialrs232 if I always have to call the SymbolicLink
(VirtualSerial)?

============================================================
Note the key point here: those names are DIFFERENT NAMES! The first is in
the GLOBAL?? namespace, and is the internal name of the device driver, and
is visible only to other device drivers. The second is in the Device space,
and is the user-visible name. You cannot open a kernel internal name from
user space, and this is deliberately done to prevent potential security
violations that could occur if an application could open some low-level
driver.

C) I installed a DeviceIOControl monitor to check why my code is failing
with Error 50 (The request is not supported) and I can’t figure why.

It sounds like you are sending an invalid request. Can you show the
CTL_CODE macro that defines the operation you are using, and make sure you
show the definitions of the driver-specific names used in CTL_CODE? (That
is, show the definition of the first and second parameters to CTL_CODE)

The output of the DeviceIOControl monitor is here:
http://img254.imageshack.us/img254/5439/picggi.png

All I saw was a completely black window

The ones from test.exe are my code, the other (protected) is the original
application calling the same device.

My code is like this:

#include “stdafx.h”
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>

void ErrorExit(LPTSTR lpszFunction){
// Retrieve the system error message for the last-error code

LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

// Display the error message and exit the process

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) *
sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT(“%s failed with error %d: %s”),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT(“Error”), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
================
Just as a footnote: you should never call ExitProcess. Or Exit. Or do
anything other than return from the main function. These bad habits lead to
code that is unmaintainable.
================
}

BOOL OpenDevice(PWSTR DriverName, HANDLE lphDevice){

WCHAR DeviceName[MAX_PATH]; HANDLE hDevice;

if ((GetVersion() & 0xFF) >= 5) {
wcscpy(DeviceName, L"\\.\Global\“);
} else {

wcscpy(DeviceName, L”\\.\"); }
wcscat(DeviceName, DriverName); printf(“Opening… %S\n”,
DeviceName);
hDevice = CreateFileW(DeviceName, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hDevice == INVALID_HANDLE_VALUE) {
printf(“CreateFile() ERROR %d\n”, GetLastError()); return FALSE;

}

lphDevice = hDevice; return TRUE;
================
Try not to put more than one statement on a line. The code becomes
unreadable.
================
}

int _tmain(int argc, _TCHAR
argv[]){

HANDLE hDevice = NULL;
DWORD cb = 0;
int ret = 0;
char tcode[] = “\x8a\xb3\x39\x9d”; /
Copied from original request seen on
Monitor) */

if(!OpenDevice(L"MyDeviceName",&hDevice)) {

printf(“Error: Error opening device\n”);
return(0);
} else {

printf(“Device succesfully opened!\n”);

}

char *Buff = (char *)VirtualAlloc(NULL, 0x330, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
===================================
I find the recurring occurrence of random constants more than a little
disturbing. What does 0x330 mean? Or in decimal, 816? Why would you call
VirtualAlloc to allocate a 816-byte buffer? This doesn’t make any sense.
Why not call malloc()? Or even HeapAlloc? But VirtualAlloc? Wrong API!

If the buffer size is a constant, why not write

char Buff[0x330];

which makes more sense?
===================================

if (Buff){

ret = DeviceIoControl(hDevice, 0xa028442f, tcode, 0x04, 0, NULL, &cb,
(LPOVERLAPPED)NULL);
===================================
What is that nonsense 0xA028442f? I have NEVER seen such an insane piece of
code! The ONLY valid argument that can appear there is either a CTL_CODE
macro or a symbol defined in terms of the CTL_CODE macro!

#define SOME_OPERATION CTL_CODE(…parmeters…)

You do not need to cast NULL to an (LPOVERLAPPED)

And what is the meaning of 0x04? In a sane world, this would be specified
in a way that was completely dependent on the contents of tcode. For
example, “strlen(tcode)” or something else reasonable.

Where did the random device type 0xA028 come from? It is 41000. This sort
of looks like a reasonable device type, but it would be defined as
#define MY_DEVICE 41000
and we would see
CTL_CODE(MY_DEVICE, …other parameters…)

Now, the bits 0xa028442f & 0xC000 would give me the access type, that is
4000, or 0100 0000 0000 0000. Code 01 is FILE_READ_ACCESS, and the
low-order 2 bits, 11, indicate METHOD_NEITHER. So the very LEAST that
should be there is

CTL_CODE(MY_DEVICE, …, METHOD_NEITHER, FILE_READ_ACCESS)

so you need to know what the symbol is for defining the device (41000) and
the symbolic name of the actual operation value, 4363. So you should see
something in a header file of the form

#define MY_DEVICE 41000
#define SOME_OPERATION 4363
#define IOCTL_SOME_OPERATION CTL_CODE(MY_DEVICE, SOME_OPERATION,
METHOD_NEITHER, FILE_READ_ACCESS)

If you got any one of these wrong, you will get the “not supported” error,
so the generation of this magical random number is very suspect. The
canonical code in a driver is

switch(stk->Parameters.DeviceIoControl.IoControlCode)
{
case …:
…do something;
break;
case …:
…do something else;
break;
default:
Irp->IoStatus.status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp);
return STATUS_NOT_SUPPORTED;
}

so my first suspicion is that the random number 0xA028442f is not one of the
known cases, so the default is taken. So why do you believe this is a valid
IoControlCode?
=======================================================

if (ret == 0) {
printf(“Error: Bytes returned %#x\n”,cb);
ErrorExit(TEXT("DeviceIoControl: "));
}

}

CloseHandle(hDevice);
return(0);
}

I always get this error:

C:>Test.exe Opening… .\Global\MyDeviceName Device succesfully opened!
Error: Bytes returned 0 DeviceIOControl: Error 50 - The request is not
supported

Why?
========================
See above code example. Explain how you got that number for the IOCTL code.
========================

Thanks


NTDEV is sponsored by OSR

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


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.</strsafe.h></stdio.h></windows.h>

Hi Tim Roberts

Thanks for your reply, very useful.

Symbolic links can be used to create (nearly) arbitrary names in the
kernel namespace. The only names which can be used from user mode with
CreateFile are the names within the \DosDevices namespace. In user
space, \. is mapped to \DosDevices. So, a symbolic link declared as
“\DosDevices\MyDriver” can be opened from user mode as “\\.\MyDriver”

In virtually every case, that’s what you’ll see symbolic links used for
in drivers.

Interesting. Enumerating all my drivers with this tool (http://esagelab.com/resources.php?s=bootkit_remover) I found that I only have two device drivers that has this \DosDevices\ - they are COM1 and LPT1.

All the others has \Devices\, and I noted that a few of them I’m able to open calling \.\DriverName - Do you know why I’m able to open a few of this devices as Administrator (user-space) if they do not start with \DosDevices\?

Also, I noted that a few entries that has very different names in SymbolicLink and Destination entry, I’m only able to open the one listed in SymbolicLink (“\GLOBAL??\FPSfilter”).

That sounds very strange to me, I only see two \DosDevices\, I can open a few of this drivers starting with \.\SomeDriverName and also I may open sometimes a few of this SymbolicLink (“\GLOBAL??\FPSfilter”).

Also, if I log with a restricted account (not administrator) I’m able to open at least one of this SymbolicLink (“\GLOBAL??\FPSfilter”), but it failed with permission denied (ERROR 5) at CreateFileW() for all others. I liked this tool (http://esagelab.com/resources.php?s=bootkit_remover) because it allows me to list all drivers and their SymbolicLink and Destination, but it does not show the permissions of those device drivers. There is a tool that allows me to list all Device Drivers SymbolicLink and Destination like this tool but also show what user is able to open each of them for read and write?

With restricted user (not administrator) I only was able to open SymbolicLink (“\GLOBAL??\FPSfilter”), all other fails with access denied. I tried to replace the GENERIC_READ and GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE and the same happens.

I mean, it’s OK drivers has different permissions, but for example I have a Antivirus installed and it has a driver and I can’t open it. But, if I open the Antivirus icon with restricted user I’m able to manage it, like ask to it scan the system, etc and I believe this commands are sent to kernel-land via this driver, right? So, why I can’t open it if the GUI application that I call with restricted access is able to do it?

86DB3F68 is also likely to be a kernel address rather than an ioctl
code. If you can attach a debugger to the application you’re reverse
engineering, you can set a breakpoint on DeviceIoControl and see what
the real parameters are.

I’m downloading a debugger (ollydb) and I will do it and post here, thanks for suggestion.

Your first one (A028442F) would be METHOD_NEITHER. This one (86DB3F68)
would be METHOD_BUFFERED, but I doubt that’s what it is.

How do you know what is METHOD_NEITHER or METHOD_BUFFERED just by looking at the hex-value (0xA028442F and 0x86DB3F68)?

Before your post, this hex-values (IOCTL control codes) passed as parameter to DeviceIoControl Function was “randomly” chosen by the driver developer. For example, they could control and choose any IOCTL code number of any task without follow any rule, like for example I can create any name to a function (except the reserved ones) my idea was that a developer could use whatever number he wanted.

Looking more carefully at documentation I see:

"dwIoControlCode [in]
The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.

For a list of the control codes, see Remarks. The documentation for each control code provides usage details for the lpInBuffer, nInBufferSize, lpOutBuffer, and nOutBufferSize parameters."

http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx

However I can’t find a documentation to dissect a IoControlCode, for example to identify if it’s METHOD_NEITHER or METHOD_BUFFERED like you did, what is the permission, or whatever other information I can get from it. Can you point me some document that will help me in this task? Preferably a documentation for dummies. :slight_smile:

Note that this call has both an input buffer and an output buffer. You
are not providing an output buffer.

I fixed it, on my first code I had it, but I removed just to test since it was failing and I forgot to add again.

DeviceIoControl(hDevice, 0xa028442f, tcode, (DWORD)0x04, Buff, 0x330, &cb, (LPOVERLAPPED)NULL);

As I said, depending on the driver type, it’s quite possible the driver
has some kind of security check built in, so that it can only be used by
certain applications.

In general how these protections are implemented? By name of the process? Name of the process and path? I did a test, replacing my binary name and path with the original file and I get the same problem, so this is not how this drivers are protected or my drive (that I’m testing to learn) is not protected.

Thank you so much.

At the risk of stating the obvious here: IOCTL control codes are
defined by MSFT for standard devices and there are #define IOCTL_XXX
definitions for those control codes in standard include files. IOCTL
control codes for nonstandard devices are defined by the
designer/programmer of the nonstandard device driver and have
definitions in some include file that may or may not be provided by
the author.

You cannot just send control code values you think ought to work to
some device, you have to send the correct control code values with the
correct argument values within a possibly stateful sequence of events.

Code that reads:

DeviceIoControl(hDevice, 0xa028442f, tcode, (DWORD)0x04, Buff, 0x330,
&cb, (LPOVERLAPPED)NULL);

Is just broken code. An error result is the expected result.

You need to find the DOCUMENTED interface for this device and use that.

The CTL_CODE macro and the documentation for its use in the WDK
“Defining I/O Control Codes” explains the bits. However, at the risk
of being accused of restating what I just said: You need to find the
DOCUMENTED interface for this device and use that.

Mark Roddy

On Tue, Oct 19, 2010 at 2:30 PM, wrote:
> Hi Tim Roberts
>
> Thanks for your reply, very useful.
>
>>Symbolic links can be used to create (nearly) arbitrary names in the
>>kernel namespace. ?The only names which can be used from user mode with
>>CreateFile are the names within the \DosDevices namespace. ?In user
>>space, \. is mapped to \DosDevices. ?So, a symbolic link declared as
>>“\DosDevices\MyDriver” can be opened from user mode as “\\.\MyDriver”
>
>>In virtually every case, that’s what you’ll see symbolic links used for
>>in drivers.
>
> Interesting. Enumerating all my drivers with this tool (http://esagelab.com/resources.php?s=bootkit_remover) I found that I only have two device drivers that has this \DosDevices\ - they are COM1 and LPT1.
>
> All the others has \Devices\, and I noted that a few of them I’m able to open calling \.\DriverName - Do you know why I’m able to open a few of this devices as Administrator (user-space) if they do not start with \DosDevices\?
>
> Also, I noted that a few entries that has very different names in SymbolicLink ?and Destination entry, I’m only able to open the one listed in SymbolicLink (“\GLOBAL??\FPSfilter”).
>
> That sounds very strange to me, I only see two \DosDevices\, I can open a few of this drivers starting with \.\SomeDriverName and also I may open sometimes a few of this SymbolicLink (“\GLOBAL??\FPSfilter”).
>
> Also, if I log with a restricted account (not administrator) I’m able to open at least one of this SymbolicLink (“\GLOBAL??\FPSfilter”), but it failed with permission denied (ERROR 5) at CreateFileW() for all others. I liked this tool ?(http://esagelab.com/resources.php?s=bootkit_remover) because it allows me to list all drivers and their SymbolicLink ?and Destination, but it does not show the permissions of those device drivers. There is a tool that allows me to list all Device Drivers SymbolicLink and Destination like this tool but also show what user is able to open each of them for read and write?
>
> With restricted user (not administrator) I only was able to open SymbolicLink (“\GLOBAL??\FPSfilter”), all other fails with access denied. I tried to replace the GENERIC_READ and GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE and the same happens.
>
> I mean, it’s OK drivers has different permissions, but for example I have a Antivirus installed and it has a driver and I can’t open it. But, if I open the Antivirus icon with restricted user I’m able to manage it, like ask to it scan the system, etc and I believe this commands are sent to kernel-land via this driver, right? So, why I can’t open it if the GUI application that I call with restricted access is able to do it?
>
>>86DB3F68 is also likely to be a kernel address rather than an ioctl
>>code. ?If you can attach a debugger to the application you’re reverse
>>engineering, you can set a breakpoint on DeviceIoControl and see what
>>the real parameters are.
>
> I’m downloading a debugger (ollydb) and I will do it and post here, thanks for suggestion.
>
>>Your first one (A028442F) would be METHOD_NEITHER. ?This one (86DB3F68)
>>would be METHOD_BUFFERED, but I doubt that’s what it is.
>
> How do you know what is METHOD_NEITHER or METHOD_BUFFERED just by looking at the hex-value (0xA028442F and 0x86DB3F68)?
>
> Before your post, this hex-values (IOCTL control codes) passed as parameter to DeviceIoControl Function was “randomly” chosen by the driver developer. For example, they could control and choose any IOCTL code number of any task without follow any rule, like for example I can create any name to a function (except the reserved ones) my idea was that a developer could use whatever number he wanted.
>
> Looking more carefully at documentation I see:
>
> “dwIoControlCode [in]
> The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.
>
> For a list of the control codes, see Remarks. The documentation for each control code provides usage details for the lpInBuffer, nInBufferSize, lpOutBuffer, and nOutBufferSize parameters.”
>
> http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx
>
> However I can’t find a documentation to dissect a IoControlCode, for example to identify if it’s METHOD_NEITHER or METHOD_BUFFERED like you did, what is the permission, or whatever other information I can get from it. Can you point me some document that will help me in this task? Preferably a documentation for dummies. :slight_smile:
>
>>Note that this call has both an input buffer and an output buffer. ?You
>>are not providing an output buffer.
>
> I fixed it, on my first code I had it, but I removed just to test since it was failing and I forgot to add again.
>
> DeviceIoControl(hDevice, 0xa028442f, tcode, (DWORD)0x04, Buff, 0x330, &cb, (LPOVERLAPPED)NULL);
>
>>As I said, depending on the driver type, it’s quite possible the driver
>>has some kind of security check built in, so that it can only be used by
>>certain applications.
>
> In general how these protections are implemented? By name of the process? Name of the process and path? I did a test, replacing my binary name and path with the original file and I get the same problem, so this is not how this drivers are protected or my drive (that I’m testing to learn) is not protected.
>
> Thank you so much.
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

> Interesting. Enumerating all my drivers with this tool (http://esagelab.com/resources.php?

s=bootkit_remover) I found that I only have two device drivers that has this \DosDevices\ - they are
COM1 and LPT1.

Look at \GLOBAL?? - at least all drive letters for disk volumes are there.

right? So, why I can’t open it if the GUI application that I call with restricted access is able to do it?

Set the proper ACL to the device.

In general how these protections are implemented? By name of the process?

By ACL usually.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi Joseph M. Newcomer

Thanks a lot for your help, very helpful.

Note the key point here: those names are DIFFERENT NAMES! The first is in
the GLOBAL?? namespace, and is the internal name of the device driver, and
is visible only to other device drivers. The second is in the Device space,
and is the user-visible name. You cannot open a kernel internal name from
user space, and this is deliberately done to prevent potential security
violations that could occur if an application could open some low-level
driver.

Thanks for clarification, now I understand, but my tests (probable wrong) show different results as I wrote a few minutes ago.

Enumerating all my drivers with this tool (http://esagelab.com/resources.php?s=bootkit_remover) I found that I only have two device drivers that has this \DosDevices\ - they are COM1 and LPT1.

All the others has \Devices\, and I noted that a few of them I’m able to open calling \.\DriverName - Do you know why I’m able to open a few of this devices as Administrator (user-space) if they do not start with \DosDevices\?

Also, I noted that a few entries that has very different names in SymbolicLink and Destination entry, I’m only able to open the one listed in SymbolicLink (“\GLOBAL??\FPSfilter”).

That sounds very strange to me, I only see two \DosDevices\, I can open a few of this drivers starting with \.\SomeDriverName and also I may open sometimes a few of this SymbolicLink (“\GLOBAL??\FPSfilter”).

Also, if I log with a restricted account (not administrator) I’m able to open at least one of this SymbolicLink (“\GLOBAL??\FPSfilter”), but it failed with permission denied (ERROR 5) at CreateFileW() for all others. I liked this tool (http://esagelab.com/resources.php?s=bootkit_remover) because it allows me to list all drivers and their SymbolicLink and Destination, but it does not show the permissions of those device drivers. There is a tool that allows me to list all Device Drivers SymbolicLink and Destination like this tool but also show what user is able to open each of them for read and write?

With restricted user (not administrator) I only was able to open SymbolicLink (“\GLOBAL??\FPSfilter”), all other fails with access denied. I tried to replace the GENERIC_READ and GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE and the same happens.

I mean, it’s OK drivers has different permissions, but for example I have a Antivirus installed and it has a driver and I can’t open it. But, if I open the Antivirus icon with restricted user I’m able to manage it, like ask to it scan the system, etc and I believe this commands are sent to kernel-land via this driver, right? So, why I can’t open it if the GUI application that I call with restricted access is able to do it?

It sounds like you are sending an invalid request. Can you show the
CTL_CODE macro that defines the operation you are using, and make sure you
show the definitions of the driver-specific names used in CTL_CODE? (That
is, show the definition of the first and second parameters to CTL_CODE)

I don’t have this information because I don’t have the source code of the driver. I’m using a driver developed by a third-party (not supported anymore) and the source code is not available.

That’s why I used a IOCTL monitor to try get this informations to communicate with this device driver.

With the IrpTracker.exe tool I’m not able to get all this information from a sent request instead of get from the source code definition?

Also, before your post, these hex-values (IOCTL control codes) passed as parameter to DeviceIoControl Function was “randomly” chosen by the driver developer in my mind. For example, they could control and choose any IOCTL code number of any task without follow any rule, like for example I can create any name to a function (except the reserved ones) my idea was that a developer could use whatever number he wanted.

Looking more carefully at documentation I see:

"dwIoControlCode [in]
The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.

For a list of the control codes, see Remarks. The documentation for each control code provides usage details for the lpInBuffer, nInBufferSize, lpOutBuffer, and nOutBufferSize parameters."

http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx

However I can’t find a documentation to dissect a IoControlCode, for example to identify if it’s METHOD_NEITHER or METHOD_BUFFERED like you did, what is the permission, or whatever other information I can get from it. Can you point me some document that will help me in this task? Preferably a documentation for dummies. :slight_smile:

All I saw was a completely black window

Strange, I can access it and I see a piece of the IrpTracker.exe tool screenshot http://img254.imageshack.us/img254/5439/picggi.png

Just as a footnote: you should never call ExitProcess. Or Exit. Or do
anything other than return from the main function. These bad habits lead to
code that is unmaintainable.

Thanks for the suggestion, very appreciated. But I can’t use return() since the function that I call ExitProcess() is a void function. Anyway, I will change the type of the function to return a valid or bad code and do a clean return() on the main function. Thanks again.

Try not to put more than one statement on a line. The code becomes unreadable.

Where? I don’t see it in my code. Maybe a problem when I copied? I mean, I call one function per line, that’s a bad development practice? You mean that I should break long lines with \ ?

I find the recurring occurrence of random constants more than a little
disturbing. What does 0x330 mean? Or in decimal, 816? Why would you call
VirtualAlloc to allocate a 816-byte buffer? This doesn’t make any sense.
Why not call malloc()? Or even HeapAlloc? But VirtualAlloc? Wrong API!

If the buffer size is a constant, why not write

char Buff[0x330];

which makes more sense?

You are right again, I will fix it.

Yes, I random chose this size, just as a test, it could be any size, I was just testing.

What is that nonsense 0xA028442f? I have NEVER seen such an insane piece of
code!

I’m ashamed! :stuck_out_tongue:

This 0xA028442f is the IOCTL code that I got from the IOCTL monitoring tool, at least, I did believe it was…

The ONLY valid argument that can appear there is either a CTL_CODE
macro or a symbol defined in terms of the CTL_CODE macro!

#define SOME_OPERATION CTL_CODE(…parmeters…)

Humm…

You do not need to cast NULL to an (LPOVERLAPPED)

And I need to cast the nInBufferSize and nOutBufferSize to DWORD?

And what is the meaning of 0x04? In a sane world, this would be specified
in a way that was completely dependent on the contents of tcode. For
example, “strlen(tcode)” or something else reasonable.

You are right, I modified the code so may times trying to make it work that it has a lot of very bad code, sorry about that. once I get it working I will re-write the whole code to make it better / clean it.

Where did the random device type 0xA028 come from?

From the IOCTL monitor. Also, I was not aware that this code was broken and not a whole number.

It is 41000.

How do you know if you don’t know the device driver? Or all has to start with 4100? Where I can find a list of this valid device type?

This sort of looks like a reasonable device type, but it would be defined as
#define MY_DEVICE 41000
and we would see
CTL_CODE(MY_DEVICE, …other parameters…)

Now, the bits 0xa028442f & 0xC000 would give me the access type, that is
4000, or 0100 0000 0000 0000. Code 01 is FILE_READ_ACCESS, and the
low-order 2 bits, 11, indicate METHOD_NEITHER. So the very LEAST that
should be there is

Where you got the 0xC000 from?

At CreateFile() I see that FILE_READ_ACCESS is 01, but where you got the reference to METHOD_NEITHER?

CTL_CODE(MY_DEVICE, …, METHOD_NEITHER, FILE_READ_ACCESS)

so you need to know what the symbol is for defining the device (41000) and
the symbolic name of the actual operation value, 4363. So you should see
something in a header file of the form

#define MY_DEVICE 41000
#define SOME_OPERATION 4363
#define IOCTL_SOME_OPERATION CTL_CODE(MY_DEVICE, SOME_OPERATION, METHOD_NEITHER, FILE_READ_ACCESS)

Did you get this values from MY_DEVICE and SOME_OPERATION from your experience just as a example, right? I’m afraid that you “guessed” this numbers from my example, and if is the case I’m not following you.

If you got any one of these wrong, you will get the “not supported” error,
so the generation of this magical random number is very suspect. The
canonical code in a driver is

switch(stk->Parameters.DeviceIoControl.IoControlCode)
{
case …:
…do something;
break;
case …:
…do something else;
break;
default:
Irp->IoStatus.status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp);
return STATUS_NOT_SUPPORTED;
}

Now it make much more sense why I’m getting that error.

so my first suspicion is that the random number 0xA028442f is not one of the
known cases, so the default is taken. So why do you believe this is a valid
IoControlCode?

Because I got it from a IOCTL monitor tool that grab all IOCTL requests and show it in a user-friendly interface.

Thanks a lot for all your help.

xxxxx@googlemail.com wrote:

Because I got it from a IOCTL monitor tool that grab all IOCTL requests and show it in a user-friendly interface.

I see two possibilities. One, the IOCTL tracker is lying to you.
Running with a debugger might answer that question. Two, the ioctl
number is a security code, perhaps generated through some algorithm
based on the time.


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

Hi Mark Roddy

Thanks, your answer was useful since I’m a beginner.

So, IOCTL control codes for nonstandard devices (third-party / no MS) may have any value from 0x00000001 until 0xFFFFFFFF?

This link (http://msdn.microsoft.com/en-us/library/ff543023(VS.85).aspx) is very nice!
Thanks

Hi Maxim S. Shatskih

Thanks. What API is used to define ACL of a device?

Do you know a tool that allows me to list all devices and the ACL of each of them?

Thanks

Actually for a NON-Microsoft driver doing only non-standard things the
values are between 0x80000000 and 0xFFFFFFFFF see
http://www.osronline.com/ddkx/kmarch/irps_1l0n.htm

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@googlemail.com” wrote
in message news:xxxxx@ntdev:

> Hi Mark Roddy
>
> Thanks, your answer was useful since I’m a beginner.
>
> So, IOCTL control codes for nonstandard devices (third-party / no MS) may have any value from 0x00000001 until 0xFFFFFFFF?
>
> This link (http://msdn.microsoft.com/en-us/library/ff543023(VS.85).aspx) is very nice!
> Thanks

xxxxx@googlemail.com wrote:

Thanks, your answer was useful since I’m a beginner.

So, IOCTL control codes for nonstandard devices (third-party / no MS) may have any value from 0x00000001 until 0xFFFFFFFF?

No. The ioctl code consists of several different fields, and some of
them MUST be correct in order to be processed. The bottom-most two bits
(bits 1 and 0) specify the buffering. That determines how I/O manager
copies or maps the user’s buffers to and from kernel space. Bits 15 and
14 (0x0000C000) determine the permissions that are required to use the
ioctl. If you set the bits to require write permission, but the driver
was opened with read permission, the ioctl will be rejected.

Bits 31 to 16 are supposed to identify your “device type”, and there is
a range defined for users (0x8000 to 0xffff). Bits 13 to 2 specify the
function code. Technically speaking, all of the bits other than the
buffering and the permissions can be set to whatever you want. No one
really cares about the device type. However, for consistency, you
should choose a device type and stick with it.

So, in effect, you get 12 bits to have “whatever you want”.


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

Tim Roberts

Thanks, I’m still debugging it (I’m learning how to debug).

I was able to do it with my test app and set a breakpoint with BPX kernel32.DeviceIoControl at Olly Debugger, but curiously I don’t see any reference for this call on my target application.

I will keep you updated

Thanks