Oceania is at war with obcaseinsensitive; Oceania has always been at war with obcaseinsensitive

by Michael S. Kaplan, published on 2010/12/08 07:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2010/12/08/10101148.aspx


I remember when I first read 1984.

It was a few years after the original publishing, as I was not born until over two decades later and I was quite lazy in my pre-zygote reading phase....

Anyway, the thing about 1984 that struck me at the time, that distracted me to no end, was how stupidly it portrayed people.

I mean the notion that people could yell at the top of their lungs about their longtime enemy Eastasia and their longtime ally Eurasia, only to reverse the roles minutes after a news announcement?

I remember asking the teacher whether that was like when my mom would say vegetables were good for me when I knew she was dead wrong but to keep the peace I let her false statement stand.

No, she explained, in 1984 these people truly believed what they were saying.

"Well then," I concluded, "they were stupid!"

The teacher pulled a quote out of bumper sticker, suggesting that I never underestimate the power of human stupidity.

Good advice (probably 50% of the interesting things this teacher ever said to me!). But I digress.....

Anyway, it turns out I was wrong back then.

It wasn't stupidity that was at issue here, it was the [possibly subconscious] recognition that the situation has changed and re-aligning themselves with the new situation. Instantly. Since the memory has no benefit in this situation, hanging onto it would be doubleplusungood.

Which brings me to today's blog.

And obcaseinsensitive.

Regular readers might remember my Blitzkrieging the landscape.NET (aka in this case, two) (aka When is obcaseinsensitive not ObCaseInsensitive?) from early 2008.

It talked about a registry key. A registry key that was always a particular setting unless people changed it - which was rare.

It explained how for the sake of ASP.Net, the Developer Division's CLR took that registry key and decided to always change it. Even though that broke some people. And essentially made the value entirely useless since it was reseting the people who had changed it andf there was no way back.

I probably wasn't much of a fan of ASP.Net before, but I freaking hated them after that, most of the time....

Then this mail came the other day to one of those DLs I belong to:

Hi All,

I am using the code below to do a case sensitive file search.  
hFind = FindFirstFileEx(argv[1], FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, FIND_FIRST_EX_CASE_SENSITIVE); statement does not seem to work as documented FindFirstFileEx Function (Windows).

File on disk: "D:\TestFindFirstFile\Debug\Test.txt"
Input : "D:\TestFindFirstFile\Debug\test.txt"

Excepted Result : FindFirstFileEx to fail giving error indicating that the files differs in case.
Actual Result : FindFirstFileEx does not fail nor indicate files differs in case.

Please clarify if this is behavior by design or if this is issue or am I using the API incorrectly.

Thanking you in advance.


#include <windows.h>
#include <tchar.h>
#include <stdio.h>

void _tmain(int argc, TCHAR *argv[]) {
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   if( argc != 2 ) {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Target file is %s\n"), argv[1]);
   hFind = FindFirstFileEx(argv[1], FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, FIND_FIRST_EX_CASE_SENSITIVE);
   if (hFind == INVALID_HANDLE_VALUE) {
      printf ("FindFirstFileEx failed (%d)\n", GetLastError());
      return;
   } else {
      _tprintf (TEXT("The first file found is %s\n"), FindFileData.cFileName);
      FindClose(hFind);
   }
}

And then came the reason:

Is HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\obcaseinsensitive set to 1?

If you want this API to work as documented, you'll need to set this regkey to 0.  Setting it to zero has the effect of enabling case sensitivity across the system.  Although this is notionally opt-in (Win32 apps tend to opt-in) at the NT layer it's really opt-out (you get case sensitive unless you ask for insensitive.)  The practical effect of this is changing the registry key "lights up" latent bugs in NT applications and drivers that are not expecting case sensitive behavior.  So if you change this registry key, things might work - but they also might not, because they're probably not tested.
 
You might then assume that seeing this key is 1 means you can ignore case sensitivity.  That's not really a valid assumption either.  After all, files could have been put on a disk differing only by case when the key was 0, and now it's 1, but those files are still there.  Or, you could be talking to a network share where your client promises to not create files differing only by case, but not all clients make the same promise.  Etc, etc.

At this point, since pretty much every machine has this registry value set to 1, a flag that only works if it is set to 0 is a fairly useless bit of documentation in FindFirstFileEx for the FIND_FIRST_EX_CASE_SENSITIVE flag.

I mean, is there any point in claiming otherwise? It is just a waste of time to pretend one would ever think it was something one might expect to be 0. A developer certainly shouldn't write code against it assuming a 0 will be there....

Especially since Windows sets obcaseinsensitive to 1, and Windows has always set obcaseinsensitive to 1.

Well, as far as any of us know.

And at last, I have won the victory over myself. At last I love obcaseinsensitive.

Um, hang on, that analogy broke down in the end.

I'll work on it....


ErikF on 8 Dec 2010 11:33 AM:

I have SFU installed on my computer and remember getting asked about this one. It was asked in a very scary way ("If you enable this, your system might blow up and the world will end!"), but I enabled it anyways and it hasn't affected anything that I can see. My guess as to why this is the case is because in the Windows world case-sensitive files have never been the norm, so few if any programs actually use the FIND_FIRST_EX_CASE_SENSITIVE flag. I actually prefer this behaviour myself: I don't like having to hunt for oddball configuration files in Unix that I missed because the designers wanted to be different and use uppercase!

Joshua on 10 Dec 2010 9:58 AM:

So installation of ASPNET sets obcaseinsensitive to 1. I'll have to remember that next time I need case sensitive.

Michael S. Kaplan on 10 Dec 2010 10:13 AM:

Actually, the update was given to everybody whether they were using ASP.Net or not. They thought that woukd be a good idea.

Maurits [MSFT] on 11 Dec 2010 7:44 AM:

Breaks POSIX compliance, surely.

Michael S. Kaplan on 11 Dec 2010 11:34 AM:

Maybe not -- since you can change on reg key to get back the way it was. Besides, who cares about POSIX compliance, these days? :-)

Nick Lowe on 22 Feb 2012 4:37 AM:

I have, hopefully, fully explained obcaseinsensitive, FILE_CASE_SENSITIVE_SEARCH and FIND_FIRST_EX_CASE_SENSITIVE in all their gory details on my blog:

www.nicklowe.org/.../understanding-case-sensitivity-in-windows-obcaseinsensitive-file_case_sensitive_search

Comments gratefully received!

Cheers,

Nick


Please consider a donation to keep this archive running, maintained and free of advertising.
Donate €20 or more to receive an offline copy of the whole archive including all images.

go to newer or older post, or back to index or month or day