[NOOB] [FILTER DRIVER] problem setting flag after iocreatedevice

hello,
first of all i’m sorry for my “strange” english, i’ll do my best to be understandable.

And may it’s a double post (not sure of the first one cause i didn’t validate my inscription first)

So, i’m a very noob in driver writing.
But i succed in writing a kind of hello world driver (using DbgPrnt for the message output). it compiles and works fine.

But it’s not my goal.

May be i should explain the goal and context first.

I’m using a well known driver to read write ports on windows XP (it’s smport.sys)
But the source code of this driver is not available.

Well i need to write a filter driver to log smport activity and eventually modify it.

I talk about filter driver because i understand that is exactlly the purpose of this stuff. Am i right?

So, i made a first attempt… a very simple filter that only pass trhu all irps to smport.

is it clear?

so , i used IOCreateDevice if it’s not clear i will post some code later but i’m not in front of my box right now.

What i understand for the next step is i MUST define my “new” device flags exactly like smport flags.

After some research i finally descover “devicetree”…

but when i look at /device/smport to see the interpreted flags here’s what i see:
HAS_NAME <— i think i don’t care for my filter am i right?

NEITHER_IO <— i think this one is very important am i right?

but this line don’t compile at all:

pMyFilterDeviceObject ->Flags = pMyFilterDeviceObject -> Flags | DO_NEITHER_IO ;

the message is DO_NEITHER_IO undeclared

I’m confused.

So i tried DO_BUFFERED_IO just to see if it compiles.
And yes it compiles.
But it’s not the good flag.

So how to set the flag to NEITHER_IO?

I have plenty of other boring noob questions :wink:
But let’s begin with this one.

Well i’m sorry with my question but it’s not so easy for a beginner, so…

Thank you in advance.

xxxxx@gmail.com wrote:

May be i should explain the goal and context first.

I’m using a well known driver to read write ports on windows XP (it’s smport.sys)
But the source code of this driver is not available.

Well i need to write a filter driver to log smport activity and eventually modify it.

I talk about filter driver because i understand that is exactlly the purpose of this stuff. Am i right?

Not really. Writing a filter driver will tell you what requests are
received by smport.sys. It will not tell you what smport.sys actually does.

so , i used IOCreateDevice if it’s not clear i will post some code later but i’m not in front of my box right now.

What i understand for the next step is i MUST define my “new” device flags exactly like smport flags.

After some research i finally descover “devicetree”…

but when i look at /device/smport to see the interpreted flags here’s what i see:
HAS_NAME <— i think i don’t care for my filter am i right?
NEITHER_IO <— i think this one is very important am i right?

but this line don’t compile at all:

pMyFilterDeviceObject ->Flags = pMyFilterDeviceObject -> Flags | DO_NEITHER_IO ;

the message is DO_NEITHER_IO undeclared

I’m confused.

Right. There is no symbol called “DO_NEITHER_IO”. If you do not
specify either DO_BUFFERED_IO or DO_DIRECT_IO, then you will get
“neither”. That’s where the name comes from.

So how to set the flag to NEITHER_IO?

Just don’t set anything.


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

Ok thank you very much for your quick answer. You are great!

So ok, if i don’t set flags i assume i don’t have to

pMyFilterDeviceObject ->Flags = pMyFilterDeviceObject -> Flags & ~DO_DEVICE_INITIALIZING;

but may be i have to. Please can you confirm?

the second point is when you say:

“Not really. Writing a filter driver will tell you what requests are received by smport.sys. It will not tell you what smport.sys actually does.”

for now, i know what the driver do in theory:
it can write a byte or a word or a long word to a port adress.

I say in theory because in fact it’s what the old .vxd version of this driver do (I have the source code in plain C of the .vxd) and i think that the .sys “find a way” to do the same thing.

The first step i’d like to do is to make something like a logfile that show something like
READ VALUE ADDRESS or WRITE VALUE ADDRESS…

I know it will not be easy but you make me in trouble.
I really thought a filter driver was the solution.

No?

Another solution is (may be) to rewrite a kind of smport.sys from scratch but as you know i’m a beginner and i think it will be a little bit easier and in fact the right way to write a filter driver.

As a new driver writer, I would strongly suggest you use KMDF instead of
WDM. You will get a functioning driver much more quickly (for instance,
this Flags setting problem would have been taken care of for you by the
framework). You will only be able to create a log of access if the
smport driver only touches the ports based off of incoming I/O (which is
what Tim was saying). If smport touches the i/o ports outside of the
context of a PIRP, you will not know about it from your filter.

Anyways, to answer your question about setting the flags, you should
really do this

pMyFilterDeviceObject->Flags |= AttachedDevice->Flags &
(DO_POWER_PAGABLE | DO_POWER_INRUSH | DO_BUFFERED_IO | DO_DIRECT_IO)

and then clear DO_DEVICE_INITIALIZING later.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, May 23, 2007 1:42 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] [NOOB] [FILTER DRIVER] problem setting flag after
iocreatedevice

Ok thank you very much for your quick answer. You are great!

So ok, if i don’t set flags i assume i don’t have to

pMyFilterDeviceObject ->Flags = pMyFilterDeviceObject -> Flags &
~DO_DEVICE_INITIALIZING;

but may be i have to. Please can you confirm?

the second point is when you say:

“Not really. Writing a filter driver will tell you what requests are
received by smport.sys. It will not tell you what smport.sys actually
does.”

for now, i know what the driver do in theory:
it can write a byte or a word or a long word to a port adress.

I say in theory because in fact it’s what the old .vxd version of this
driver do (I have the source code in plain C of the .vxd) and i think
that the .sys “find a way” to do the same thing.

The first step i’d like to do is to make something like a logfile that
show something like
READ VALUE ADDRESS or WRITE VALUE ADDRESS…

I know it will not be easy but you make me in trouble.
I really thought a filter driver was the solution.

No?

Another solution is (may be) to rewrite a kind of smport.sys from
scratch but as you know i’m a beginner and i think it will be a little
bit easier and in fact the right way to write a filter driver.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

xxxxx@gmail.com wrote:

So ok, if i don’t set flags i assume i don’t have to

pMyFilterDeviceObject ->Flags = pMyFilterDeviceObject -> Flags & ~DO_DEVICE_INITIALIZING;

but may be i have to. Please can you confirm?

You still have to clear that flag.

the second point is when you say:

“Not really. Writing a filter driver will tell you what requests are received by smport.sys. It will not tell you what smport.sys actually does.”

for now, i know what the driver do in theory:
it can write a byte or a word or a long word to a port adress.

I say in theory because in fact it’s what the old .vxd version of this driver do (I have the source code in plain C of the .vxd) and i think that the .sys “find a way” to do the same thing.

The first step i’d like to do is to make something like a logfile that show something like
READ VALUE ADDRESS or WRITE VALUE ADDRESS…

I know it will not be easy but you make me in trouble.
I really thought a filter driver was the solution.

No?

That depends on what your long-term goal is. Your filter will sit on
top of smport.sys. When an application sends a request to smport.sys,
your filter driver will see the request. Thus, you can see what the
application is asking for. Then, you send it on to smport.sys. Your
driver doesn’t get involved again until the request is complete and on
its way back to the application. At that point, you can see what
smport.sys is returning to the application.

In between those steps, your filter will not have any clue about what
smport.sys is actually doing. It is not involved.

Another solution is (may be) to rewrite a kind of smport.sys from scratch but as you know i’m a beginner and i think it will be a little bit easier and in fact the right way to write a filter driver.

No, I disagree completely. Writing a simple I/O port tweaker from
scratch is much easier than writing a filter driver. In fact, the DDK
contains the full source code for a driver that does exactly that:
src\general\portio. Rewriting that in KMDF would be a few hundred lines
of code at most.


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

Doron Holan said:

" As a new driver writer, I would strongly suggest you use KMDF instead of WDM (…)"

Thank you very much for the advise, well so much to know…
So i assume KMDF stands for Kernel Mode Driver FrameWork.
I don’t know (yet) if this framework is a standard part of the DDK.

May be it’s important to precise that i’m a new driver coder as well as a new C coder. It’s the hardway, i know. In fact i don’t have Visual studio and i use the DDK because it’s free and the build process is quite easy.

I have to say i’m very surprised by the fact that someone @microsoft.com answer me. And it’s a very good surprise! Thank you very much to give me a part of your time. Helping newcomers like you do is a great support and no doubt a great thing for microsoft’s image (i don’t know if it’s very correct in english).

In general (for all contributors) it’s a great thing to see your skill level and your kindness. When i wrote my first line, i thought nobody helps me.The fact is it’s not true.

Tim Roberts said:

“Your filter will sit on top of smport.sys. When an application sends a request to smport.sys, your filter driver will see the request. Thus, you can see what the application is asking for. Then, you send it on to smport.sys. Your driver doesn’t get involved again until the request is complete and on its way back to the application. At that point, you can see what smport.sys is returning to the application.”

For my first purpose it’s enough i think.

Tim Roberts said:

“No, I disagree completely. Writing a simple I/O port tweaker from scratch is much easier than writing a filter driver. In fact, the DDK contains the full source code for a driver that does exactly that: src\general\portio. Rewriting that in KMDF would be a few hundred lines of code at most.”

So, ok i will have a look to portio. And i’ll try to understand the code. And may be i will use this code for all new programs i will write. It’s much more confortable to have the source code of all part of the solution.

For now, one poblem is i’m a delphi coder and many of my programs are using smport.sys.
I really don’t want to touch too much the “smport” part of those programs. So if i write a simple I/O port tweaker from scratch, it have to do exactly the same thing that smport.sys do (+= eventually a log function). It’s good if i can replace smport.sys by mystuff.sys in the code and that’s all.

The second problem is
i have to code a program doing the same thing than an old program + many new functions.
The old program access ports and send “something” via smport.sys
The source code of this program and the coder are no longer available.
The firm that develop the prog no longer exists.

I have to know what is send to rewrite the same thing.
As a delphi coder it’s a challenge to write c code for drivers but it’s a nightmare if i have to run a debugger to find ports and data in the old (—>threaded<—) prog.

Why?

Because I’m really not at all a super ASM coder. In fact, i never tried and i’m really not sure i want to try. And also because i’m not sure i want to log a thread with a break point a paper and a pen. It will be nice if the computer do that for me.

So i’ll stop posting for a while.
If i have some new problems, i’ll try to focus on technical points and give you some code to help you to help me.

Thanks all.

[FINALLY]
[PART 1 OF THE PROBLEM SOLVED]

With your help i’m now able to attach my device to smport, and it’s runnig fine.
All Irps pass thru the filter without any problem.
I have also debugged the unload call back and have no blue screen anymore when exiting.

What a pity that we can’t put a flag solved on top of the post.

So thank’s again.

The next part will be more complicated i’m afraid.

because

pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;

and

pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;

will not work.

in fact everything is DEVICE_CONTROL

so write
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;

is not a problem.
The big problem is i really don’t know what to do in the
DispatchDeviceControl function.

So if you feel generous enogh to help me with the next step don’t hesitate :slight_smile:

Most drivers outside of the file systems and storage do not really use
read and write because they do not deal with byte streams. This is
probably why smport has method neither i/o set in the device object, it
is irrelevant to the operation of the device. KMDF is a part of the
WDK. Again, I strongly recommend you start your project using a KMDF
sample, you will have much fewer roadblocks. In this case, you should
look at %wdkroot%\6000\src\kmdf\toaster\filter.

As for what to do with the incoming IOCTLs, that is a tough problem.
Since you don’t know what the definitions or structures related to the
IOCTLs are, you have a lot of reverse engineering to do. The buffering
type (neither, direct, buffered) for an IOCTL is encoded in the IOCTL
value itself (vs the buffering type for reads and writes which is set on
the device), so you can start with dumping the input buffer. Then, set
a completion routine and dump the output buffer.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, May 24, 2007 5:12 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] [NOOB] [FILTER DRIVER] problem setting flag after
iocreatedevice

[FINALLY]
[PART 1 OF THE PROBLEM SOLVED]

With your help i’m now able to attach my device to smport, and it’s
runnig fine.
All Irps pass thru the filter without any problem.
I have also debugged the unload call back and have no blue screen
anymore when exiting.

What a pity that we can’t put a flag solved on top of the post.

So thank’s again.

The next part will be more complicated i’m afraid.

because

pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;

and

pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;

will not work.

in fact everything is DEVICE_CONTROL

so write
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
DispatchDeviceControl;

is not a problem.
The big problem is i really don’t know what to do in the
DispatchDeviceControl function.

So if you feel generous enogh to help me with the next step don’t
hesitate :slight_smile:


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

xxxxx@gmail.com wrote:

The next part will be more complicated i’m afraid.
because
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
and
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
will not work.

in fact everything is DEVICE_CONTROL

so write
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;

is not a problem.
The big problem is i really don’t know what to do in the
DispatchDeviceControl function.

So if you feel generous enogh to help me with the next step don’t hesitate :slight_smile:

You said you write Delphi applications that call into this driver,
right? Then your Delphi application is calling DeviceIoControl. Every
DeviceIoControl call results in an IRP_MJ_DEVICE_CONTROL request to a
driver. The IRP contains fields that hold the ioctl number, the input
buffer size, the output buffer size, and a pointer to the buffer that
you passed in. The data will be whatever your application put there.


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

Thank’s.
Ok i promise you i will have a look to
%wdkroot%\6000\src\kmdf\toaster\filter

After all if an effort is done to make my life simpler, it’s a good thing to honnor the effort.
The thing afraid me, is to have to begin something new again.
I’m in a dynamic way and i never try to do something like that before.
I’m very afraid to give up if i do not understand KMDF.

Doron Holan said:

“As for what to do with the incoming IOCTLs, that is a tough problem.
Since you don’t know what the definitions or structures related to the
IOCTLs are, you have a lot of reverse engineering to do. The buffering
type (neither, direct, buffered) for an IOCTL is encoded in the IOCTL
value itself (vs the buffering type for reads and writes which is set on
the device).”

Let see if i understand well what you are saying:
IOCTL value is a code that say the buffering method, the acces type (read or write) and so on.
So if my next step is just to say… something read or something write. I have to decode IOCTL value? right?

So if i’m right i think it’s a DWORD value (32 bits).
I assume it’s a dword because the msdn said:

The DeviceIoControl function sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation.

and the prototype is

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

Ok, so if i understand well the second parameter is the IOCTL we are currently talking to.
If i’m able to decode this value, i should at least know what is the function called in the driver and the buffering method.

Right?

Tim Roberts said:

You said you write Delphi applications that call into this driver,
right? Then your Delphi application is calling DeviceIoControl. Every
DeviceIoControl call results in an IRP_MJ_DEVICE_CONTROL request to a
driver. The IRP contains fields that hold the ioctl number, the input
buffer size, the output buffer size, and a pointer to the buffer that
you passed in. The data will be whatever your application put there.

You are perfectly right!
I just realize i’m on the way! (see my previous post)

The fact is i use a component that manage the DeviceIoControl and all the stuff for me. Hidding in fact the interesting side of the iceberg.

so, the light is on now… At least for my program (because remember there’s a second point)

Have a look (soory it’s pascal syntax):

dwReadByteCode := CTL_CODE(SMALLPORT_TYPE, $901, METHOD_BUFFERED, FILE_READ_ACCESS);

dwWriteByteCode := CTL_CODE(SMALLPORT_TYPE, $902, METHOD_BUFFERED, FILE_WRITE_ACCESS);

dwReadWordCode := CTL_CODE(SMALLPORT_TYPE, $903, METHOD_BUFFERED, FILE_READ_ACCESS);

dwWriteWordCode := CTL_CODE(SMALLPORT_TYPE, $904, METHOD_BUFFERED, FILE_WRITE_ACCESS);

dwReadDWordCode := CTL_CODE(SMALLPORT_TYPE, $905, METHOD_BUFFERED, FILE_READ_ACCESS);

dwWriteDWordCode := CTL_CODE(SMALLPORT_TYPE, $906, METHOD_BUFFERED, FILE_WRITE_ACCESS);

Cute isn’t it?

And now this one for exemple:

PortResult:=DeviceIoControl(hDevice, dwReadByteCode, @Index, sizeof(Index),@value, sizeof(value), cbBytesReturned,nil);

I think a big part of the solution in theory is under my eyes while CTL_CODE function is in fact

function CTL_CODE(DeviceType: integer; func: integer; meth: integer; access: integer): DWORD;
Begin
result := (DeviceType shl 16) or (Access shl 14) or (func shl 2) or (meth);
end;

The point is now to write a decode function (i’m not very familar with bytes manipulation) and di that in a correct plain C.

But if i perfecly understand all waht you are saying, i’m near something very important to succed in the next step.

Trust me, WDM requires you to understand way more than KMDF does. Think
of it this way, WDM requires you to do everything, even the things you
don’t care about just to get your driver running (like setting the Flags
on your device object, why does it matter for a filter?). KMDF, on the
other hand, lets you focus only on what you are trying to do, focusing
in on only on the things that you need to think about.

The IOCTL value is a ULONG. Normally a driver knows the IOCTL values it
will support and the contracts that come with that IOCTL and how it is
processed. In this case drivers treat the IOCTL as 32 bit value. You
are reverse engineering the ioctl, so you will have to break the IOCTL
value into its 4 pieces. Bug, given your previous posts, you have the
IOCTL values. Look at the macro CTL_CODE in wdm.h

#define CTL_CODE( DeviceType, Function, Method, Access ) (
\
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) |
(Method) \
)

The 4 pieces are device type, function, method, access. You can focus
on method and ignore the other 3 for determining where the buffers live
in the IRP. Again, from wdm.h

//
// Macro to extract buffering method out of the device io control code
//
#define METHOD_FROM_CTL_CODE(ctrlCode) ((ULONG)(ctrlCode & 3))

//
// Define the method codes for how buffers are passed for I/O and FS
controls
//

#define METHOD_BUFFERED 0
#define METHOD_IN_DIRECT 1
#define METHOD_OUT_DIRECT 2
#define METHOD_NEITHER 3

You can use METHOD_FROM_CTL_CODE to extract the method and then look at
the buffers based on the method returned to you. I will leave it up to
you to figure out which method maps to what buffer in the PIRP (and as
an additional plug for KMDF, KMDF takes care of all of this for you and
just gives you a buffer :wink: ). Again, given your previous post, you are
dealing only with METHOD_BUFFERED.

In light of this where you have the app which is talking to the smport
driver, I don’t really see what value you are getting by adding a
filter. Your filter will see the same data that your application does,
the filter will not give you any window into how smport writes the data
to the output buffer though.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, May 24, 2007 11:22 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] [NOOB] [FILTER DRIVER] problem setting flag after
iocreatedevice

Thank’s.
Ok i promise you i will have a look to
%wdkroot%\6000\src\kmdf\toaster\filter

After all if an effort is done to make my life simpler, it’s a good
thing to honnor the effort.
The thing afraid me, is to have to begin something new again.
I’m in a dynamic way and i never try to do something like that before.
I’m very afraid to give up if i do not understand KMDF.

Doron Holan said:

“As for what to do with the incoming IOCTLs, that is a tough problem.
Since you don’t know what the definitions or structures related to the
IOCTLs are, you have a lot of reverse engineering to do. The buffering
type (neither, direct, buffered) for an IOCTL is encoded in the IOCTL
value itself (vs the buffering type for reads and writes which is set on
the device).”

Let see if i understand well what you are saying:
IOCTL value is a code that say the buffering method, the acces type
(read or write) and so on.
So if my next step is just to say… something read or something write.
I have to decode IOCTL value? right?

So if i’m right i think it’s a DWORD value (32 bits).
I assume it’s a dword because the msdn said:

The DeviceIoControl function sends a control code directly to a
specified device driver, causing the corresponding device to perform the
corresponding operation.

and the prototype is

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

Ok, so if i understand well the second parameter is the IOCTL we are
currently talking to.
If i’m able to decode this value, i should at least know what is the
function called in the driver and the buffering method.

Right?


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Well, the portio sample uses hex 910 911 and 912 instead of 904, 905, 906- otherwise, it matches your specs directly.

So if I were you, I’d go to the portio sample, change the constants in GPIOCTL.H for the device type (can’t tell if it needs changing from what’s here), the IOCTL codes as noted above, change sources to name the output file smport.sys, build it, and drop it in.

Good odds it will probably just work (or at least be very close, in which case you can ask focused questions to close any remaining gap).

I’ve seen these sort of drivers before, they usually aren’t much more than a straight knockoff of the sample (must have been a nice way to make a quick buck for someone)…

thank’s a lot:

In a previous post, i also said that i have (for job purpose) to rewrite an equivalent of an old software and adding some functions to this one and deliver a new documentation and source code.

But i haven’t got the source of this soft. Docs are lost. And the firm no longer exists.

The only good point is the software also use smport.sys

Since i’ve got no idea of what is send that’s why i want to make a filter.
You see?

I want to thank you all again.
You are an incredible great support for me.

It’s amazing.

xxxxx@gmail.com wrote:

Have a look (soory it’s pascal syntax):

I used to be a huge Delphi fan. I was even a beta tester for Delphi 2
and 3. All of that ended when I found Python, which has now stolen my
heart away.

dwReadByteCode := CTL_CODE(SMALLPORT_TYPE, $901, METHOD_BUFFERED, FILE_READ_ACCESS);
dwWriteByteCode := CTL_CODE(SMALLPORT_TYPE, $902, METHOD_BUFFERED, FILE_WRITE_ACCESS);
dwReadWordCode := CTL_CODE(SMALLPORT_TYPE, $903, METHOD_BUFFERED, FILE_READ_ACCESS);
dwWriteWordCode := CTL_CODE(SMALLPORT_TYPE, $904, METHOD_BUFFERED, FILE_WRITE_ACCESS);
dwReadDWordCode := CTL_CODE(SMALLPORT_TYPE, $905, METHOD_BUFFERED, FILE_READ_ACCESS);
dwWriteDWordCode := CTL_CODE(SMALLPORT_TYPE, $906, METHOD_BUFFERED, FILE_WRITE_ACCESS);

Cute isn’t it?

This is good. METHOD_BUFFERED is the easiest kind to handle. The I/O
manager copies the user’s data into a nice, safe kernel buffer for you.
Your driver can read the information directly from that buffer.

The CTL_CODE macro was taken directly from the C headers.

And now this one for exemple:

PortResult:=DeviceIoControl(hDevice, dwReadByteCode, @Index, sizeof(Index),@value, sizeof(value), cbBytesReturned,nil);

Yes, that’s just what I would expect. On the way in, the buffer will
have the index of the I/O port to be read. The driver will read the I/O
port and write the value in the same buffer. The I/O manager will then
copy the results back into the application buffer.

The point is now to write a decode function (i’m not very familar with bytes manipulation) and di that in a correct plain C.

You don’t need a decode function. The CTL_CODE macro produces a
constant, and it is that constant you’ll see in the IRP. The C
equivalent of the above would be

#define ReadByteCode CTL_CODE(SMALLPORT_TYPE, 0x901, METHOD_BUFFERED, FILE_READ_ACCESS)
#define WriteByteCode CTL_CODE(SMALLPORT_TYPE, 0x902, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define ReadWordCode CTL_CODE(SMALLPORT_TYPE, 0x903, METHOD_BUFFERED, FILE_READ_ACCESS)
#define WriteWordCode CTL_CODE(SMALLPORT_TYPE, 0x904, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define ReadDWordCode CTL_CODE(SMALLPORT_TYPE, 0x905, METHOD_BUFFERED, FILE_READ_ACCESS)
#define WriteDWordCode CTL_CODE(SMALLPORT_TYPE, 0x906, METHOD_BUFFERED, FILE_WRITE_ACCESS)

You’ll need to define SMALLPORT_TYPE before this, but you should be able
to get that from your source.

So, if you do your filter in KMDF, your DeviceIoControl handler is
handed an IoControlCode as the last parameter. Your code would do:
if( IoControlCode == ReadByteCode )
or
switch( IoControlCode )
{
case ReadByteCode:

Traditionally in C, #define constants like this are all upper case, but
that’s a stylistic thing for you to decide on.


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

A quick buck or two is really it. I went into one firm that had a driver
from a previous consultant that they had paid $30K for, you guessed it it
was GPIO with the Microsoft copyright removed and no other changes!


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“Bob Kjelgaard” wrote in message
news:xxxxx@ntdev…
Well, the portio sample uses hex 910 911 and 912 instead of 904, 905, 906-
otherwise, it matches your specs directly.

So if I were you, I’d go to the portio sample, change the constants in
GPIOCTL.H for the device type (can’t tell if it needs changing from what’s
here), the IOCTL codes as noted above, change sources to name the output
file smport.sys, build it, and drop it in.

Good odds it will probably just work (or at least be very close, in which
case you can ask focused questions to close any remaining gap).

I’ve seen these sort of drivers before, they usually aren’t much more than
a straight knockoff of the sample (must have been a nice way to make a
quick buck for someone)…

xxxxx@gmail.com wrote:

I want to thank you all again.
You are an incredible great support for me.

It’s amazing.

Ah, you got lucky. We usually string up the newbies and feed them to
the lions. :wink:

Just don’t ask about C++…


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

Aldric- if the portio sample with the changes I mentioned works as a replacement for smport.sys [and it probably does], then you can add your logging directly to it and skip dealing with a filter driver. You also have source code for your replacement driver as well as the app you are attempting to reverse engineer- thus a complete solution with no missing source (except for the Windows I/O manager and HAL, anyway) and no mysteries.

You can try it in a few minutes time, and if it works or is even close to working, it will save you the time of writing a filter (any filter) from scratch, which is much larger, and leaves you with a future problem if smport should become unavailable.

But it is your time to use.

-----Original Message-----
From: aldric.gilbert

thank’s a lot:

In a previous post, i also said that i have (for job purpose) to rewrite an equivalent of an old software and adding some functions to this one and deliver a new documentation and source code.

But i haven’t got the source of this soft. Docs are lost. And the firm no longer exists.

The only good point is the software also use smport.sys

Since i’ve got no idea of what is send that’s why i want to make a filter.
You see?

Hey i’m glad to be lucky!
I’m reading the portio code and i think you’re right folks.
I think tomorrow morning i’ll try to compile portio and i have the feeling it will works fine.
I’m not totally sure but i begin to think smport is portio with a spiderman suit.

by the way i think i will save time.

But in fact, i don’t want to give up with my filter driver. This is a new universe for me and i’m really intersted by the kernel land.

I think i will buy some books and have some hard working.
And i will try not to ask about c++ because (it’s a joke not a troll) true hackers use Delphi.

Seriously i plan to learn C# for high level programming and because it looks a litlle bit like Delphi (ho well i’ll have to learn about the .net framework instead of the VCL too)
But i really have to study C and C++ for lower level programming. And may be some ASM (arrrrgggg) too.