A crash after copying data to a buffer getting from an MDL

> Note that for USB transfers, you can only transfer the maximum bulk transfer size on any transaction, e.g., 1K bytes for USB 1.0, 2K bytes for high-speed USB 2.0, etc., and since you have said nothing about the expected buffer sizes, or any attempt you are making to limit transfer sizes, there is no way to tell what is going on here. I might as well say

while this might be true at the lower bus levels of abstraction, the driver abstraction is that you can send much larger buffers in an URB and the host controller will subdivide it into bus sized pieces.

d

> Additional information about this problem. The dispatch routine to handle this IRP is at >DISPATCH_LECEL, but I change the IRQL to PASSIVE_LEVEL by KeLowerIrql()

Major bug.

Never ever do this.

This can break the entire OS.

TDI send/receive paths are fine for DISPATCH_LEVEL.


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

Joseph M. Newcomer wrote:

Note that for USB transfers, you can only transfer the maximum bulk transfer
size on any transaction, e.g., 1K bytes for USB 1.0, 2K bytes for high-speed
USB 2.0, etc., and since you have said nothing about the expected buffer
sizes, or any attempt you are making to limit transfer sizes, there is no
way to tell what is going on here.

The maximum bulk PACKET size is 64 bytes for full-speed and 512 bytes
for high-speed, but that’s almost completely irrelevant to drivers and
applications. The maximum TRANSFER size (that is, the largest buffer in
a single URB) on a 21st Century Windows system is about 3 MB. There’s a
knowledge base article with the full details.


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

disney_cheng@qq.com wrote:

I have to say sorry about this. Exactly, I use the TransferBufferMdl pointer in the URB, which is get from the IRP by using URB_FROM_IRP().

if (pUrb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
{
RtlMoveMemory(pUrb->UrbBulkOrInterruptTransfer.TransferBuffer, data, dataLength);
}
else if (pUrb->UrbBulkOrInterruptTransfer.TransferBufferMdl != NULL)
{
mdl = pUrb->UrbBulkOrInterruptTransfer.TransferBufferMdl;
buf = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);

//It will not crash without this sentence
RtlMoveMemory(buf, data, dataLength);
}

Are you absolutely sure you have received a
URB_BULK_OR_INTERRUPT_TRANSFER URB? Does the rest of the URB look
reasonable?


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

I would have suspected that the rule is, if you are not at PASSIVE_LEVEL,
don’t go there. There must be some reason you are running at
DISPATCH_LEVEL, and it is not clear that making your thread preemptible is
not going to do serious harm. My view is that if you need PASSIVE_LEVEL,
then you should be either using a work queue item or create your own passive
thread and queue requests to it. Whimsically changing a thread to
PASSIVE_LEVEL strikes me as very hazardous.
joe


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Gary G. Little
Sent: Wednesday, December 15, 2010 8:13 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A crash after copying data to a buffer getting from an
MDL

Typically the rule of thumb is if you don’t originally set IRQL you don’t
CHANGE IRQL, or you make damn sure it’s reset to where it started when you
got there. So … since you LOWERED the IRQL to do some PASSIVE level
processing, were you kind and set it BACK to DISPATCH before you left?

Gary G. Little

----- Original Message -----
From: “disney cheng” <disney_cheng>
To: “Windows System Software Devs Interest List”
Sent: Wednesday, December 15, 2010 5:26:57 AM
Subject: RE:[ntdev] A crash after copying data to a buffer getting from an
MDL

Additional information about this problem. The dispatch routine to handle
this IRP is at DISPATCH_LECEL, but I change the IRQL to PASSIVE_LEVEL by
KeLowerIrql() at the beginning of dealing with it. Because I have to use TDI
driver to send an receive datas, some functions about using TDI must be used
at IRQL < DISPATCH_LEVEL.


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


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 http:</http:> MailScanner, and is
believed to be clean.</disney_cheng>

You can find lots of stuff on the Internet; its existence does not guarantee
its correctness, reliability, or suitability for purpose.

Key here is that under limited conditions, certain code sequences give the
illusion of working. It does not guarantee that they *actually work* nor
does it guarantee that, under your conditions, it is even going to make
sense.

In other technologies, this is often referred to as “bash it with a hammer
until it fits”. Just because you need PASSIVE_LEVEL to do something does
not give you the right to arbitrarily lower the IRQL to do it. It also
means that you should not think of syntactic sequentiality as the solution
to problems; instead, you have to think about asynchronous interactions
(e.g., with worker threads), and event-driver models.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of disney_cheng@qq.com
Sent: Wednesday, December 15, 2010 9:29 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A crash after copying data to a buffer getting from an
MDL

According to the document of WDK, you are right. The parameter of
KeLowerIrql() must retrieved by KeRaiseIrql(). It’s a fatal error if not
following this rule. But I don’t think it’s the reason of the problem.
Because I saw some one else did this, and it works well. I found a virtual
usb bus driver on the internet, and look into it’s IRP process, the IRPs in
bulk or interrupt transfer are all sent at Dispatch Level and finished at
Passive Level. It means that, the virtual usb bus driver lower the IRQL
without raising it back before completing the IRP.
I think the operation of changing the IRQL won’t be treated as a mistake by
the system. But it’s easily cause mistakes because many interface function
have to work at prescriptive IRQL.

I thought the rule was that you never lower IRQL if you didn’t raise it
in
the first place.


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.

I think the problem is that we keep teaching students that programs execute
in syntactic order. Drivers are a case where asynchronous event-driven
models are the appropriate solution, but I find new driver writers caught up
in the freshman-C-programming syntactic sequentiality model (I see this in
application programming also). So if you are trying to be sequential, and
you need PASSIVE_LEVEL, the obviously correct solution is to set passive
level. The other model is the “I once saw someone write code that looked
like this, and I found it on the Internet”, which is what we were seeing
here.

I hope someone rewrote the piece of trash smart card driver; I’ve seen
people say “But we followed a model we found in the Microsoft source
examples” without realizing the smart card driver is NOT a Microsoft source
example, even though it was in the old DDK sources. And for real trash,
some of the MSDN examples are fatally flawed beyond recovery (which I
attribute to hiring summer interns between their freshman and software years
and having no adult supervision).

It is a serious failure of our education system that we don’t teach people
to be suspect of code examples and not accept them blindly, especially when
the provenance is questionable (“I found it on the Internet”) and thus the
reliability is not guaranteed.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Scott Noone
Sent: Wednesday, December 15, 2010 11:26 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] A crash after copying data to a buffer getting from an
MDL

But it can run correctly. Further more, it load the USBTOR driver as I do.

If you corrupt a memory buffer and the system continues to run, does it mean
that it isn’t a bug to corrupt the memory buffer? By lowering the IRQL of
the processor you’re breaking a contract with the O/S, just because it
doesn’t crash immediately doesn’t mean that it isn’t a bug.

Writing drivers is hard and has unique challenges, such as dealing with
IRQL. You can’t just exempt yourself from the rules because it’s easier.

Also, try running Driver Verifier on your driver and see if the system
crashes then.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

Hope to see you at the next OSR kernel debugging class February 14th in
Columbia, MD!


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.

Hi, all

First of all, thanks for all your help. The problem has been figured out. You are right. The reason is the crass operation that lowering the IRQL. I do the test without the operation, no crash any more.
I have to modify the network module which can only run at Passive Level at present.
Thank you all again!

Joseph M. Newcomer wrote:

I think the problem is that we keep teaching students that programs execute
in syntactic order.

This qualifies as Joe’s “profound nugget of the week”. Perhaps if F#
starts making some popular inroads, we can eliminate this bias.


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

May (insert your favorite deity here) save us all from that day.

Next, we’ll be taking about Haskell…

Peter
OSR

Hello, everyone

I don’t konw if I should create a new subject. Anyway, I need your help again. Now I’m trying to deal with the TDI module. I have to handle the IRP at Dispatch Level, if I put the TDI request into a work item or a new thread. How do I know when it was finished? You must have already know that, at Dispatch Level, I can not use KeWaitForSingleObject().

You’re still trying to think sequentially. As long as you think
sequentially in an asynchronous event-driven system you are doomed. Your
failure is thinking the right thing to to do now is write
A(); Enqueue work item for B(); Wait for workitem to complete; C();
Which is just your old sequentiality problem all over again! You have
solved nothing.

Supposed you had to do A(); B(); C();

You discover you are at DISPATCH_LEVEL but B() must be called at
PASSIVE_LEVEL

There are several approaches. The most commone one is to study what C() is
doing and whether or not it REQUIRES that you be at DISPATCH_LEVEL. If not,
you can do

A(); Enqueue work item for X();
X() { B(); C(); }

But you really, really have to understand what the code is, and stop thiking
that you must do it in the syntactic sequence
A(); B(); C();

If C() *must* be executed at DISPATCH_LEVEL, I might code it as either of
these: (and others may tell me this is wrong, so wait for replies)

A(); Enqueue work item for X();
X() { B(); Requst a DPC for Y();}
Y() { C(); }
**** [Note this is a real cheat]

A(); Enqueue work item for X();
X() { KSPIN_LOCK L;
KIRQL irql;
B();
KeInitializeSpinLock(&L);
KeAcquireSpinLock(&L, &irql);
C();
KeReleaseSpinLock(&L, irdl);
}

Key here is making sure correct context is maintained across all these
calls. Again, a major failure is teaching that context is kept in local
variables, and this won’t work in the example above. You have to allocate
heap-based packets to hold state. But it is all based on an asynchronous
event-driven model.

Note that anything computed in A() but required in B() must be preserved so
it can be used in B(). This can be done in the device extension (if you can
only have a maximum of one transaction of this nature at a time) or in the
heap, which is probably the preferable approach. Similarly, anything
computed in A() and used in C() must be passed into the execution context of
C().

Of course, if you require that A() and C() execute in the same
DISPATCH_LEVEL thread and no context swap is permitted between them, you are
doomed. This won’t ever happen. As soon as you queue up that passive
thread request, you are done with your current context, and you will never
again be in that context.

Since we don’t have a good picture of everything you are trying to do, it is
not clear what to advise you to do. But you need to carefully think out the
contexts required.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of disney_cheng@qq.com
Sent: Friday, December 17, 2010 2:49 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A crash after copying data to a buffer getting from an
MDL

Hello, everyone

I don’t konw if I should create a new subject. Anyway, I need your help
again. Now I’m trying to deal with the TDI module. I have to handle the IRP
at Dispatch Level, if I put the TDI request into a work item or a new
thread. How do I know when it was finished? You must have already know that,
at Dispatch Level, I can not use KeWaitForSingleObject().


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.

Hi, Joe

Thanks for your answer.

The A(), B(), C() can concrete describe as:
A(): Entry of the IRP handling routine, get the virtual address of the MDL provided by the IRP. Now is at Dispatch Level.
B(): Sending and receiving datas using TDI. Now is at Passive Level.
C(): Completing the IRP. It has to be at Dispatch Level.

The solution you said below is really true of the IRQL requirement:
A(); Enqueue work item for X();
X() { KSPIN_LOCK L;
KIRQL irql;
B();
KeInitializeSpinLock(&L);
KeAcquireSpinLock(&L, &irql);
C();
KeReleaseSpinLock(&L, irdl);
}

The IRP will be completed at Dispatch Level. But we don’t know what happen in the system during the B() part, since it’s at Passive Level. Maybe several preemptions occur.
Now I see that the point is B(). Whatever solution was used, it’s lowering the IRQL between the process of a Dispatch Level IRP. Maybe I should try to make B() work at Dispatch Level by using other interface functions instead of TdiBuildInternalDeviceControlIrp() and KeWaitForSingleObject().

-----Original Message-----
You’re still trying to think sequentially. As long as you think
sequentially in an asynchronous event-driven system you are doomed. Your
failure is thinking the right thing to to do now is write
A(); Enqueue work item for B(); Wait for workitem to complete; C();
Which is just your old sequentiality problem all over again! You have
solved nothing.

Supposed you had to do A(); B(); C();

You discover you are at DISPATCH_LEVEL but B() must be called at
PASSIVE_LEVEL

There are several approaches. The most commone one is to study what C() is
doing and whether or not it REQUIRES that you be at DISPATCH_LEVEL. If not,
you can do

A(); Enqueue work item for X();
X() { B(); C(); }

But you really, really have to understand what the code is, and stop thiking
that you must do it in the syntactic sequence
A(); B(); C();

If C() *must* be executed at DISPATCH_LEVEL, I might code it as either of
these: (and others may tell me this is wrong, so wait for replies)

A(); Enqueue work item for X();
X() { B(); Requst a DPC for Y();}
Y() { C(); }
**** [Note this is a real cheat]

A(); Enqueue work item for X();
X() { KSPIN_LOCK L;
KIRQL irql;
B();
KeInitializeSpinLock(&L);
KeAcquireSpinLock(&L, &irql);
C();
KeReleaseSpinLock(&L, irdl);
}

Key here is making sure correct context is maintained across all these
calls. Again, a major failure is teaching that context is kept in local
variables, and this won’t work in the example above. You have to allocate
heap-based packets to hold state. But it is all based on an asynchronous
event-driven model.

Note that anything computed in A() but required in B() must be preserved so
it can be used in B(). This can be done in the device extension (if you can
only have a maximum of one transaction of this nature at a time) or in the
heap, which is probably the preferable approach. Similarly, anything
computed in A() and used in C() must be passed into the execution context of
C().

Of course, if you require that A() and C() execute in the same
DISPATCH_LEVEL thread and no context swap is permitted between them, you are
doomed. This won’t ever happen. As soon as you queue up that passive
thread request, you are done with your current context, and you will never
again be in that context.

Since we don’t have a good picture of everything you are trying to do, it is
not clear what to advise you to do. But you need to carefully think out the
contexts required.
joe

> B(): Sending and receiving datas using TDI. Now is at Passive Level.

TDI send/receive paths work fine at DISPATCH, just do not use this ugly recommended macro to fill the IRP, and do the filling in your own code.

More so: this ugly macro requires the threaded IRP, which really imposes the requirement of PASSIVE, and, actually, non-threaded IRPs work fine with TDI.


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

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of disney_cheng@qq.com
Sent: Sunday, December 19, 2010 12:46 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A crash after copying data to a buffer getting from an
MDL

Hi, Joe

Thanks for your answer.

The A(), B(), C() can concrete describe as:
A(): Entry of the IRP handling routine, get the virtual address of the MDL
provided by the IRP. Now is at Dispatch Level.
B(): Sending and receiving datas using TDI. Now is at Passive Level.
C(): Completing the IRP. It has to be at Dispatch Level.

************************************************************
No, that was not the point of what I was saying, and you seem to have missed
it completely. You were asking about doing things at passive level from
dispatch level, and I was referring to a sequence that required A, B and C
be executed sequentially, starting with A at dispatch level. Instead, you
make a completely different example. If A() is, as you describe, the
top-level dispatch routine, then indeed it is at passive level, but you
cannot then say “now is at dispatch level”. There’s nothing you’ve
suggested about the code that would suddenly place it at DISPATCH_LEVEL.

You have said B() is sending and receiving data using TDI, but I’m not a
network driver expert, so I have no idea what the requirements are at that
level. Is it running at PASSIVE_LEVEL or DISPATCH_LEVEL? And you cannot
just wave your hands and say “now is at passive level”. You would indicate
that the call to B() is made from PASSIVE_LEVEL. Or, if the call is made a
DISPATCH_LEVEL, you would indicate this, and it is not clear what level you
start at, nor is it clear why you magically have ended up at DISPATCH_LEVEL.

You say C() completes the IRP has to be at DISPATHC_LEVEL. Actually, this
is not true; you can complete an IRP and anything < DIRQL level. You have
not indicated why you are currently at DISPATCH_LEVEL. Of course, it may be
that in the networking components, it is the nature of the completion
routine that it is actually running at DISPATCH_LEVEL (it may be that in the
networking world this is true, but in that case, you have not provided any
motivation as to why you need to go to PASSIVE_LEVEL). So I’m now unclear
as to what you are asking.

Bottom line: the problem statement is at best incoherent. Clarify what the
question is.

And when reading an example, try not to change it into some other example
and try to demonstrate equivalence.
***********************************************************

The solution you said below is really true of the IRQL requirement:
A(); Enqueue work item for X();
X() { KSPIN_LOCK L;
KIRQL irql;
B();
KeInitializeSpinLock(&L);
KeAcquireSpinLock(&L, &irql);
C();
KeReleaseSpinLock(&L, irdl);
}

The IRP will be completed at Dispatch Level. But we don’t know what happen
in the system during the B() part, since it’s at Passive Level. Maybe
several preemptions occur.

****
So it is preempted. Why does this matter? And what relationship is there
between the context in which the IRP is completed, and my hypothesized B()
segment of code?
****

Now I see that the point is B(). Whatever solution was used, it’s lowering
the IRQL between the process of a Dispatch Level IRP. Maybe I should try to
make B() work at Dispatch Level by using other interface functions instead
of TdiBuildInternalDeviceControlIrp() and KeWaitForSingleObject().

****
The key about using the worker thread is that you are NOT lowering the IRQL
of the thread running at DISPATCH_LEVEL. You are deferring the processing
to a PASSIVE_LEVEL thread, which executes in a completely different context.
So the requirements of DISPATCH_LEVEL are not violated by lowering *that*
thread’s IRQL. Note that if B() is supposed to be running at PASSIVE_LEVEL,
it also means that it assumes that it is entitled to block, or deschedule
itself in any way imaginable, and if you raise the IRQL level, you violate
*that thread’s* requirements.

Generally, IRQL levels are sacred. If you raise the IRQL level (e.g., using
the spinlock trick) then you must restore it, and during the time it is
raised, you may not violate any DISPATCH_LEVEL constraints. You should
assume that it is always unsafe to lower IRQL of a thread that expects to be
at DISPATCH_LEVEL, because it is making assumptions about not being
preempted (for example, in my above example, it would be really, REALLY bad
in C() to lower the IRQL if the spin lock was really locking something that
was potentially shared).

So we’re back to the problem of not understanding what question you are
asking. Also, across this same subject, you have asked two different
questions, and it is not clear what context you are interpreting this answer
in.
joe
*****

-----Original Message-----
You’re still trying to think sequentially. As long as you think
sequentially in an asynchronous event-driven system you are doomed. Your
failure is thinking the right thing to to do now is write
A(); Enqueue work item for B(); Wait for workitem to complete; C();
Which is just your old sequentiality problem all over again! You have
solved nothing.

Supposed you had to do A(); B(); C();

You discover you are at DISPATCH_LEVEL but B() must be called at
PASSIVE_LEVEL

There are several approaches. The most commone one is to study what C() is
doing and whether or not it REQUIRES that you be at DISPATCH_LEVEL. If not,
you can do

A(); Enqueue work item for X();
X() { B(); C(); }

But you really, really have to understand what the code is, and stop thiking
that you must do it in the syntactic sequence
A(); B(); C();

If C() *must* be executed at DISPATCH_LEVEL, I might code it as either of
these: (and others may tell me this is wrong, so wait for replies)

A(); Enqueue work item for X();
X() { B(); Requst a DPC for Y();}
Y() { C(); }
**** [Note this is a real cheat]

A(); Enqueue work item for X();
X() { KSPIN_LOCK L;
KIRQL irql;
B();
KeInitializeSpinLock(&L);
KeAcquireSpinLock(&L, &irql);
C();
KeReleaseSpinLock(&L, irdl);
}

Key here is making sure correct context is maintained across all these
calls. Again, a major failure is teaching that context is kept in local
variables, and this won’t work in the example above. You have to allocate
heap-based packets to hold state. But it is all based on an asynchronous
event-driven model.

Note that anything computed in A() but required in B() must be preserved so
it can be used in B(). This can be done in the device extension (if you can
only have a maximum of one transaction of this nature at a time) or in the
heap, which is probably the preferable approach. Similarly, anything
computed in A() and used in C() must be passed into the execution context of
C().

Of course, if you require that A() and C() execute in the same
DISPATCH_LEVEL thread and no context swap is permitted between them, you are
doomed. This won’t ever happen. As soon as you queue up that passive
thread request, you are done with your current context, and you will never
again be in that context.

Since we don’t have a good picture of everything you are trying to do, it is
not clear what to advise you to do. But you need to carefully think out the
contexts required.
joe


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.

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of disney_cheng@qq.com
Sent: Wednesday, December 15, 2010 2:50 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A crash after copying data to a buffer getting from an
MDL

I have to say sorry about this. Exactly, I use the TransferBufferMdl pointer
in the URB, which is get from the IRP by using URB_FROM_IRP().

if (pUrb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL) {
RtlMoveMemory(pUrb->UrbBulkOrInterruptTransfer.TransferBuffer, data,
dataLength); } else if (pUrb->UrbBulkOrInterruptTransfer.TransferBufferMdl
!= NULL) {
mdl = pUrb->UrbBulkOrInterruptTransfer.TransferBufferMdl;
buf = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);

//It will not crash without this sentence
RtlMoveMemory(buf, data, dataLength); }

I read the sample codes about using usb bulk transfer in WinWDK sample. The
mdl is initialized by MmBuildPartialMdl(), and the docs say we can use
MmGetSystemAddressForMdlSafe() to map or get the virtual address of the
system space. Is that correct?

*****
It goes back to several basic principles:
(a) how are you getting the ‘data’ address?
(b) what is the state of the ‘data’ values (for example, can they be
pageable?)
(c) what IRQL are you running at?
(d) what is dataLength and how do you get it? [Note: the question is
NOT ‘how did you compute it?’
although that question *is* relevant, but ‘What is it?’
Exact numeric value at the time of the copy

Also, why are you using RtlMoveMemory instead of RtlCopyMemory? I see no
evidence here that the source and target buffers overlap.
*****

If you are a filter below USBSTOR, then the IRPs you are receiving are all
URBs. In that case, there is no promise that Irp->MdlAddress contains
anything useful at all. When you get an URB, all of the useful information
is in the URB structure, including the pointer to the data buffer.
Irp->MdlAddress might contain something left over from the request that
USBSTOR received, but if so, that’s just an accident that you cannot rely
on. They might have created an IRP from scratch, and in that case
Irp->MdlAddress will be garbage.

****
Good point, I missed that aspect of it. But of course, it boils down to the
point that we have no idea if it is the source or target address that is
bogus, or the length is absurdly large, or that it might be executed from
DISPATCH_LEVEL on paged memory that is paged out, or what. Far too little
information to answer a question. I’d have spent a lot more time getting
this information before asking such a question, and would have given a lot
more context for the quesiton.
****


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


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.

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Maxim S. Shatskih
Sent: Sunday, December 19, 2010 1:17 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] A crash after copying data to a buffer getting from an
MDL

B(): Sending and receiving datas using TDI. Now is at Passive Level.

TDI send/receive paths work fine at DISPATCH, just do not use this ugly
recommended macro to fill the IRP, and do the filling in your own code.

****
What ugly recommended macro? (I’m actually curious; if there’s some ugly
macro I should be avoiding, I’d like to know what it is, but there’s no
context here by which I can infer what ugly macro you are referring to)
****

More so: this ugly macro requires the threaded IRP, which really imposes
the requirement of PASSIVE, and, actually, non-threaded IRPs work fine with
TDI.

*****
Another question to satisfy my curiosity: what’s a “threaded IRP”?
joe
*****


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


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.

> What ugly recommended macro? (I’m actually curious; if there’s some ugly

macro I should be avoiding, I’d like to know what it is, but there’s no
context here by which I can infer what ugly macro you are referring to)

TdiBuildDeviceControlIrp or such.

Another question to satisfy my curiosity: what’s a “threaded IRP”?

IRP known to the IO manager and linked to the thread. Created by IoBuildDeviceIoControlRequest and IoBuildSynchronousFsdRequest.

Non-threaded IRPs are not known to the IO manager (except the IRP allocation pool) and are not linked to any thread. Allocated by IoAllocateIrp or IoBuildAsynchronousFsdRequest.


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

Thanks. That is useful information to me; I’d not hit these before.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Maxim S. Shatskih
Sent: Monday, December 20, 2010 2:45 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] A crash after copying data to a buffer getting from an
MDL

What ugly recommended macro? (I’m actually curious; if there’s some
ugly macro I should be avoiding, I’d like to know what it is, but
there’s no context here by which I can infer what ugly macro you are
referring to)

TdiBuildDeviceControlIrp or such.

Another question to satisfy my curiosity: what’s a “threaded IRP”?

IRP known to the IO manager and linked to the thread. Created by
IoBuildDeviceIoControlRequest and IoBuildSynchronousFsdRequest.

Non-threaded IRPs are not known to the IO manager (except the IRP allocation
pool) and are not linked to any thread. Allocated by IoAllocateIrp or
IoBuildAsynchronousFsdRequest.


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


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.

“Joseph M. Newcomer” wrote in message news:xxxxx@ntdev…

Another question to satisfy my curiosity: what’s a “threaded IRP”?

Doron explained this concept nicely on his blog several years back:

http://blogs.msdn.com/b/doronh/archive/2006/07/27/681179.aspx

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

Hope to see you at the next OSR kernel debugging class February 14th in
Columbia, MD!