Hi All,
Sorry to beat a dead horse. I wanted to post results in case others
stumble upon this thread.
I'm down to a base case which demonstrates the problem: Create 2
different menu Dlls which do nothing other than implements the
minimum:
* IShellExtInit::Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
* IContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO);
* IContextMenu::GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
* IContextMenu::QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
InsertMenu always return TRUE, and GetLastError() always returns
ERROR_SUCCESS.
Only one of the Dlls will be present in the Context Menu. However,
both will respond to GetCommandString() (per SysInternal's DbgView).
The problem exists on Windows XP and Windows Vista. However, it is not
present on Windows 2000. I did not test on Windows 2003 Server since I
know I can duplicate on XP and Vista.
At this point, I have not been able to debug further - WinDbg locks my
machine when I attach to Explorer.exe. Hindsight being 20/20, this
makes sense...
Jeff
Jeffrey Walton
On Jun 5, 12:52 am, Jeffrey Walton <[EMAIL PROTECTED]> wrote:
> Hi Wei,
>
> Do you have any thoughts on incorrect usage? I'm not convinced it is
> Crypto++. Attached is the relevant code of InvokeCommand() and
> CalculateHashes(). InvokeCommand() has parallel arrays (vectors of
> strings) to keep the logic simple.
>
> Jeff
>
> HRESULT CCreateHash::InvokeCommand (
> LPCMINVOKECOMMANDINFO
> pCmdInfo )
> {
> // Friendly Name: 'MD5'
> std::vector< std::wstring > hashnames;
>
> // Hash: 47FD4214F5775826FB20FEC1091987A1
> std::vector< std::wstring > hashvalues;
>
> ...
> for( i = 0; i < files.size(); i++ )
> {
> CalculateFileHashes( files[ i ], hashnames, hashvalues );
> }
>
> ...
>
> }
>
> bool CCreateHash::CalculateFileHashes(
> const std::wstring& filename,
> std::vector< std::wstring >&
> hashnames,
> std::vector< std::wstring >&
> hashvalues )
> {
> CryptoPP::MD5 hashMD5;
> CryptoPP::HashFilter filterMD5(hashMD5);
>
> CryptoPP::SHA1 hashSHA1;
> CryptoPP::HashFilter filterSHA1(hashSHA1);
>
> CryptoPP::SHA256 hashSHA256;
> CryptoPP::HashFilter filterSHA256(hashSHA256);
>
> CryptoPP::SHA512 hashSHA512;
> CryptoPP::HashFilter filterSHA512(hashSHA512);
>
> CryptoPP::Whirlpool hashWhirlpool;
> CryptoPP::HashFilter filterWhirlpool(hashWhirlpool);
>
> std::auto_ptr<CryptoPP::ChannelSwitch>
> channelSwitch(new CryptoPP::ChannelSwitch);
>
> channelSwitch->AddDefaultRoute(filterMD5);
> channelSwitch->AddDefaultRoute(filterSHA1);
> channelSwitch->AddDefaultRoute(filterSHA256);
> channelSwitch->AddDefaultRoute(filterSHA512);
> channelSwitch->AddDefaultRoute(filterWhirlpool);
>
> try {
> CryptoPP::FileSource( StringNarrow( filename ).c_str(),
> true, channelSwitch.release() );
> }
>
> catch( CryptoPP::Exception& e ) { e; return false; } // e.what()
> catch( std::exception& e ) { e; return false; } // e.what()
> catch( ... ) { return false; }
>
> std::string digest;
> CryptoPP::HexEncoder encoder( new CryptoPP::StringSink( digest ),
> true /* uppercase */ );
>
> hashnames.clear(); hashvalues.clear();
>
> filterMD5.TransferTo( encoder );
> hashnames.push_back( StringWiden( filterMD5.AlgorithmName() ) );
> hashvalues.push_back( StringWiden( digest ) );
> digest.erase();
>
> filterSHA1.TransferTo( encoder );
> hashnames.push_back( StringWiden( filterSHA1.AlgorithmName() ) );
> hashvalues.push_back( StringWiden( digest ) );
> digest.erase();
>
> filterSHA256.TransferTo( encoder );
>
> hashnames.push_back( StringWiden( filterSHA256.AlgorithmName() ) );
> hashvalues.push_back( StringWiden( digest ) );
> digest.erase();
>
> filterSHA512.TransferTo( encoder );
>
> hashnames.push_back( StringWiden( filterSHA512.AlgorithmName() ) );
> hashvalues.push_back( StringWiden( digest ) );
> digest.erase();
>
> filterWhirlpool.TransferTo( encoder );
>
> hashnames.push_back( StringWiden( filterWhirlpool.AlgorithmName() ) );
> hashvalues.push_back( StringWiden( digest ) );
> digest.erase();
>
> return true;
>
>
>
> }
> ---------- Forwarded message ----------
> From: "Jim Barry" <[EMAIL PROTECTED]>
> Date: Jun 4, 10:14 pm
> Subject: Context Menu Extension DLLs Are Mutually Exclusive Under
>
> Vista
> To: microsoft.public.platformsdk.shell
>
> Jeffrey Walton wrote:
> > I've created a pair of (two separate) extensions: one for creating
> > file checksums; and a second for verifying. Reference: A File Checksum
> > Shell Menu ExtensionDll(http://www.codeproject.com/useritems/
> > ShellChecksum.asp).
>
> > It is apparent these are mutually exclusive on Vista (I just retested
> > on Windows 2000 - OK):
> > * Register both Create and Verify
> > - Only Create is available
>
> > * Register only Verify (unregister Create)
> > - Verify is available
>
> The problem seems to lie with cryptlib. If you comment out the
> InvokeCommand code and remove cryptlib from each project, both menu
> items start appearing. Actually I just tried making a debug build of
> your project using Crypto++ 5.5.1, and both menu items appeared, but
> then it totally crashed Explorer with heap corruption errors.
>
> --
> Jim Barry, MVP (Windows SDK)- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [EMAIL PROTECTED]
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
-~----------~----~----~----~------~----~------~--~---