aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/ExplorerFindFile.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/ExplorerFindFile.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Winamp/ExplorerFindFile.cpp')
-rw-r--r--Src/Winamp/ExplorerFindFile.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/Src/Winamp/ExplorerFindFile.cpp b/Src/Winamp/ExplorerFindFile.cpp
new file mode 100644
index 00000000..99d98c50
--- /dev/null
+++ b/Src/Winamp/ExplorerFindFile.cpp
@@ -0,0 +1,163 @@
+#include "main.h"
+#include "ExplorerFindFile.h"
+
+ExplorerFindFile::ExplorerFindFile()
+{
+}
+
+ExplorerFindFile::~ExplorerFindFile()
+{
+}
+
+void ExplorerFindFile::Reset()
+{
+ pidlList.clear();
+}
+
+// still need to make this handle zip:// entries natively to get them working as needed
+BOOL ExplorerFindFile::AddFile( wchar_t *file )
+{
+ LPSHELLFOLDER pDesktopFolder = 0;
+ if ( SUCCEEDED( SHGetDesktopFolder( &pDesktopFolder ) ) )
+ {
+ LPITEMIDLIST filepidl = 0, folderpidl = 0;
+ wchar_t folder[ MAX_PATH ] = { 0 },
+ param[ 512 ] = { 0 },
+ *filews = 0;
+ int zip = 0;
+
+ // doing this to handle zip:// entries where there is a valid file
+ // path included in the entry so extract it (from FFOD plugin code)
+ lstrcpynW( param, file, 7 );
+ if ( !lstrcmpiW( param, L"zip://" ) )
+ {
+ file += 6;
+ zip = 1;
+ }
+
+ filews = file + lstrlenW( file ) - 1;
+ if ( wcsstr( filews, L"." ) != 0 )
+ {
+ while ( filews && *filews && ( *filews != L'.' ) && ( filews != file ) )
+ {
+ filews = CharPrevW( file, filews );
+ if ( zip && *filews == L',' )
+ {
+ zip = 0;
+ }
+
+ if ( zip && *filews == L'.' )
+ {
+ zip = 0;
+ filews = CharPrevW( file, filews );
+ }
+ }
+ }
+
+ while ( filews && *filews && ( *filews != L',' && *filews != L':' && *filews != L'|' ) )
+ filews = CharNextW( filews );
+
+ if ( filews )
+ *filews = 0;
+
+ // doing this to handle foo.rsn\bar.spc so it'll just
+ // find foo.rsn (which should then be a valid entry)
+ filews = wcsstr( file, L".rsn\\" );
+ if ( filews )
+ {
+ *( filews + 4 ) = 0;
+ }
+
+ // and now get the folder path of the file
+ lstrcpynW( folder, file, MAX_PATH );
+
+ if ( PathIsRelativeW( folder ) )
+ {
+ // sort out relative files based against winamp.exe
+ wchar_t szTemp[ MAX_PATH ] = { 0 }, szTemp2[ MAX_PATH ] = { 0 };
+ GetModuleFileNameW( hMainInstance, szTemp, sizeof( szTemp ) );
+ PathRemoveFileSpecW( szTemp );
+ PathCombineW( szTemp2, szTemp, folder );
+ PathCanonicalizeW( folder, szTemp2 );
+ // and once calculated then we copy the file back
+ lstrcpynW( file, folder, MAX_PATH );
+ }
+
+ PathRemoveFileSpecW( folder );
+
+ HRESULT hr = pDesktopFolder->ParseDisplayName( NULL, 0, folder, 0, &folderpidl, 0 );
+ if ( FAILED( hr ) )
+ {
+ pDesktopFolder->Release();
+
+ return FALSE;
+ }
+
+ hr = pDesktopFolder->ParseDisplayName( NULL, 0, file, 0, &filepidl, 0 );
+ if ( FAILED( hr ) )
+ {
+ pDesktopFolder->Release();
+
+ return FALSE;
+ }
+
+ PIDLListMap::iterator itr = pidlList.begin();
+ for ( ; itr != pidlList.end(); itr++ )
+ {
+ wchar_t tmp[ MAX_PATH ] = { 0 };
+ SHGetPathFromIDListW( itr->first, tmp );
+ // the LPITEMIDLIST isn't consistant for all calls it seems and
+ // so it requires doing a physical check against the folder path
+ // rather than comparing LPITEMIDLIST values which would be nice
+ if ( !_wcsnicmp( folder, tmp, wcslen( folder ) ) )
+ {
+ itr->second.push_back( filepidl );
+ break;
+ }
+ }
+
+ // if we got here then there was no match with the currently parsed
+ // folder and so we need to add it to the pidllist for use later on
+ if ( itr == pidlList.end() )
+ {
+ std::vector<LPCITEMIDLIST> list;
+ list.push_back( filepidl );
+ //PIDLListMap::MapPair p(folderpidl, list);
+ pidlList.insert( { folderpidl, list } );
+ }
+
+ pDesktopFolder->Release();
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL ExplorerFindFile::ShowFiles()
+{
+ if(pidlList.size())
+ {
+ BOOL ret = TRUE;
+ for (PIDLListMap::iterator itr=pidlList.begin();itr!=pidlList.end();itr++)
+ {
+ if(FAILED(SHOpenFolderAndSelectItems(itr->first,(UINT)itr->second.size(),itr->second.data(),NULL))){
+ ret = FALSE;
+ }
+ }
+ Reset();
+ return ret;
+ }
+ return FALSE;
+}
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS ExplorerFindFile
+START_DISPATCH;
+CB(API_EXPLORERFINDFILE_ADDFILE, AddFile)
+CB(API_EXPLORERFINDFILE_SHOWFILES, ShowFiles)
+VCB(API_EXPLORERFINDFILE_RESET, Reset)
+END_DISPATCH \ No newline at end of file