1/13/2008

Shell API Makes sense this time

With all due respect: Shell API is powerful. No doubt about it, but it is so complex that it brings all sorts of extra stuff you don't really anticipate until it is too late. This price tag made Shell API less likely to be the first choice when facing a typical programming problem.

Today I witted a rare chance where the Shell API became the most reasonable choice.

My problem was to validate an user input and see whether it is a network path. For example, given something like \\server\share\dir1\dir2 , if the path is valid, I should return true.

When I first get this, I thought this is like a 5 minutes of work. Call FindFirstFile, if the call returns a valid handled, check whether WIN32_FIND_DATA.dwFileAttributes contains FILE_ATTRIBUTE_DIRECTORY. However, it was during my dev test, I found this FindFirstFile works fine on almost all scenario, except a very fundamental case: \\server\share. If you feed FindFirstFile with \\server\share, it will simply fail. So what do I do?

With remote impression, I found an API called NetShareCheck(). According to msdn this is what I needed. So my code became something like


 

HANDLE handle = FindFirstFile(…);

If (INVALID_HANDLE_VALUE != handle)
{

// Do what I used to do
}

else

{

//

// 15 lines of code or so to parse and setup

// the params for NetShareCheck

//


NET_API_STATUS result = NetShareCheck(…);

If (NERR_Success == result)
{

// ok this is what we want
}

}

So go to dev test again. Bah, no luck. Unfortunately NetShareCheck doesn't work the way I expected and I always get some asynchornize I/O like error. I was blocked and having a bad headache.


 

Problem always got resolved after a night of sleep. When I drive my wife to exam the next day, I suddenly realized there are shell API I might be able to use. After all, if explorer can see it, it is likely that your code using the same API can see it. I know Shell offers SHParseDisplayName (ref link) and SHGetPathFromIDList(ref link). The former one let you convert a path into Shell's "Item ID List" (ref link), and the later let you convert the item id list into its display name plus getting attributes we'd need. So my 3rd attempt wiped out all existing code and did something like this:


 

Pidl = SHParseDisplayName (szPath, xxxxx);

If (pidl)

{

hr = SHGetPathFromIDList(…pidl,…, attrResult)

if (IsWhatIWanted(attrResult))

hrRet = true;..

}


 

Did it worked? Oh yeah, flawlessly. Loved it.


 


 

Alright, now let's see how much we paid for this convenient function:

As soon as I called into ShParseDisplayName, the system loads all these jazz:


 

'Generic.exe': Loaded 'C:\Windows\System32\uxtheme.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\apphelp.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\networkexplorer.dll', No symbols loaded.

'Generic.exe': Unloaded 'C:\Windows\System32\networkexplorer.dll'

'Generic.exe': Loaded 'C:\Windows\System32\networkexplorer.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\oleaut32.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\propsys.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\wininet.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\normaliz.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\iertutil.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\mpr.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\ntlanman.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\netapi32.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\psapi.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\secur32.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\drprov.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\davclnt.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\cscapi.dll', No symbols loaded.

'Generic.exe': Loaded 'C:\Windows\System32\userenv.dll', No symbols loaded.


 

Huh, warned you, didn't I


 

沒有留言: