> Hello.
I understand that proper way of passing context data into newly created
system thread is by allocation of memo and passing it into system thread.
Now, assuming we’re in DeviceIoControl routine that can be processed in
context of any process is it ok to pass local variable address as
parameter to system thread?
****
As already pointed out, the LIFETIME of the data is critical; the data
must be valid at the point where you use it.
Local variables can be used corss-thread only in incredibly restricted
ways; for example
{
BYTE buffer[SOMESIZE];
InitiateThread(buffer);
WaitForThreadTermination()
}
will work, and this idiom appears in the old WDM driver examples for
handling PnP messages. But it represents exceptionally poor programming
practice in general (it means you are using the thread as an incredibly
complex and expensive function call), so the advice you have already
received that you must never, ever, under any normal circumstances, pass
the address of a local variable to ANY context where the use of the
pointer exceeds the lifetime of the stack. Another common error is
passing the address of a local in the ISR stack to a DPC (yes, I’ve seen
this done, and it took a lot of explanation to convince the programmer it
could not possibly have ever worked). This is why the heap is used.
Another consideration is that local buffers use up precious stack space,
and you don’t have a lot of it to burn when you are in the kernel (apps
have 1MB stacks by default; I think drivers have something like 8K, and a
good chunk of that is gone by the time your code is called)
****
I mean something like this:
ULONG localVar = 129;
Context *pCtx = ExAllocatePoolWithTag(PagedPool, sizeof(Context), ‘aaaa’);
//check
pCtx->field_one = &localVar;
PsCreateSystemThread(…/…/…/ pCtx );
Now inisde thread
Context *pCtx = (Context*)Param;
ULONG loval = *pCtx->field_one; // is it going to be really same as
localVar from above code?
*****
What you have passed is a pointer to a location in memory. What that
location means at the point where you dereference it in the thread is
problematic. That memory is going to be used for something, or maybe
doesn’t exist at all, or is used by some other driver which needed a stack
from the kernel stack pool, or is some other subroutine stack frame in the
code that initiated the thread (note that the thread can be running and do
the dereference before you return from PsCreateSystemThread, so on a
multicore system you may have the illusion that it worked, but it was
never, ever correct code.)
Essentially, EVERY location you reference in a thread must be valid at the
time of the reference, and you have essentially guaranteed that your code
cannot possibly work correctly.
*****
Thank you for response.
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