[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1140
  • Last Modified:

call wcsstr from a driver without page faulting

I'm using the 6001 build of the Microsoft WDK to build a filesystem minifilter driver. I'm playing around with some sample code and called wcsstr in a pre-op processing function for IRP_MJ_CREATE, only to find that it blue screened with PAGE FAULT IN A NONPAGED AREA.

Since I'm new to driver development, I'd like someone to help me understand what's going on. My vague understanding of what's happening is that the IRQ level that the filesystem driver is operating at is higher than the paging IRQ level - so that I cannot call anything that requires service from the paging system. Is this more or less correct?

So, I guess the code for wcsstr is not loaded into nonpaged memory. What's the best way to do this call? Somehow load it into nonpaged memory? Implement it myself without using the wcsstr call? Call a special version that I'm unaware of?

Thanks for any info.
0
jimstar
Asked:
jimstar
  • 6
  • 5
1 Solution
 
OnegaZhangCommented:
It is recommended to use safe string API, see the following in MSDN.
http://www.microsoft.com/whdc/driver/tips/SafeString.mspx
Help prevent buffer overruns in your driver! Use safe string functions
0
 
jimstarAuthor Commented:
I don't see any strstr/wcsstr equivalent functions using RtlString*. The only ones they list on MSDN are copy/cat/printf/length. http://msdn2.microsoft.com/en-gb/library/ms806616.aspx
0
 
jkrCommented:
How exaxtly are you calling that function? I assume a problem to e.g. the input parameter.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
jimstarAuthor Commented:
I was doing:

if(wcsstr(myUnicodeString.Buffer, L"mystring"))
{...}

Buffer is definitely valid.

I then wrote my own wcsstr function that does a char-by-char comparison (my_wcsstr) and substituted it in the place of wcsstr, and it works fine now. So, it was definitely an issue with calling the runtime version of wcsstr. Not sure exactly why though.
0
 
jkrCommented:
Are you linking /MD (or /MDd respectively)? If not, the CRT threading model might have caused the fault.
0
 
jimstarAuthor Commented:
Nope, I'm not. I've been using the bcz command. I went ahead and used BUILD /MD, and it gave the page fault on nonpaged area error when I plugged the crt version of wcsstr back in.

It might be possible that something else is causing the error, and perhaps the wcsstr is just a catalyst for the blue screen. I'll dig into my code a bit more and see if I can find something. Any thoughts on what kind of coding error would cause this particular blue screen?
0
 
jkrCommented:
BTW: Are you absolutely sure that the UNICODE_STRING is zero-terminated? Usually, this is not the case, since the lenght is given in UNICODE_STRING::Length. Does

size_t szLen = myUnicodeString.Length + 1;
wchar_t* pTmp = new wchar_t[szLen];

memset(pTmp,0,szLen * sizeof(wchar_t));

if(wcsstr(pTmp, L"mystring")) {

 //...
}

work?
0
 
jimstarAuthor Commented:
'new' : undeclared identifier

So, I went and did:

wchar_t pwszTemp[4000];
memset(pwszTemp, 0, 4000*sizeof(wchar_t));
memcpy(pwszTemp, nameInfo->Name.Buffer, nameInfo->Name.Length * sizeof(wchar_t));

However, that gives the following error:

19: unresolved external symbol __chkstk referenced in function _PreOperationCallback@12

I'm using the standard Windows XP x86 Free Build Environment. I've also tried the checked without luck.
0
 
jimstarAuthor Commented:
I'll copy it into a newly allocated UNICODE_STRING that has extra space at the end, and then manually set the n+1 character to null. I'll post the results here a little later today.
0
 
jkrCommented:
>>memcpy(pwszTemp, nameInfo->Name.Buffer, nameInfo->Name.Length * sizeof(wchar_t));

That won't work - 'Length' is the 'length in bytes of the string stored in Buffer' (http://msdn2.microsoft.com/en-us/library/aa492030.aspx), thus twice the amount of characters.

memcpy(pwszTemp, nameInfo->Name.Buffer, nameInfo->Name.Length);

or

wcsncpy(pwszTemp,nameInfo->Name.Buffer, nameInfo->Name.Length/2);

will work.

>>19: unresolved external symbol __chkstk

Try making that a global variable for that purpose.
0
 
jimstarAuthor Commented:
Looks like that did it. Thanks!

Any idea why UNICODE_STRING is popular in the DDK? Speed perhaps?
0
 
jkrCommented:
Well, the kernel APIs all take UNICODE_STRINGs as arguments, that's why this struct is favoured. Even though that thing about the length given as the *byte* count really helps everybody to shoot themseves in the foot at least once...
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now