From 0f7bb778503871051df14927c04aeb3f4cf0aeff Mon Sep 17 00:00:00 2001 From: bright-tools Date: Fri, 13 Dec 2013 14:50:13 +0000 Subject: [PATCH] Updates #12 by reading information from the bookmark links --- src/cmdln.h | 1 + src/dir_list.c | 43 +++++++++++--- src/shrtcut.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ src/shrtcut.h | 6 ++ 4 files changed, 193 insertions(+), 8 deletions(-) create mode 100755 src/shrtcut.c create mode 100755 src/shrtcut.h diff --git a/src/cmdln.h b/src/cmdln.h index e1be558..72793c8 100755 --- a/src/cmdln.h +++ b/src/cmdln.h @@ -81,6 +81,7 @@ void init_cmdln( config_container_t* const p_config ); int process_cmdln( config_container_t* const p_config, const int argc, char* const argv[] ); int process_env( config_container_t* const p_config ); +#define _DEBUG #if defined _DEBUG #define DEBUG_OUT( ... ) do { fprintf(stdout,"wd: " __VA_ARGS__ ); fprintf(stdout,"\n"); fflush(stdout); } while( 0 ) #else diff --git a/src/dir_list.c b/src/dir_list.c index c01160f..0dfa152 100755 --- a/src/dir_list.c +++ b/src/dir_list.c @@ -226,6 +226,7 @@ dir_list_t load_dir_list( const config_container_t* const p_config, const char* } #if defined _WIN32 +#include "shrtcut.h" #include #include static dir_list_t load_dir_list_from_favourites( const config_container_t* const p_config, const char* const p_fn ) @@ -238,6 +239,9 @@ static dir_list_t load_dir_list_from_favourites( const config_container_t* const DIR* FD; DEBUG_OUT("got favourites drectory: %s", path); /* TODO: recurse sub-directories */ + + CoInitialize( NULL ); + if (NULL != (FD = opendir (path))) { struct dirent* in_file; @@ -251,26 +255,47 @@ static dir_list_t load_dir_list_from_favourites( const config_container_t* const { size_t len = strlen( in_file->d_name ); if(( len > 4 ) && - ( 0 == stricmp( &(in_file->d_name[len-4]), ".ini" ))) { - char path[ MAXPATHLEN ]; + ( 0 == stricmp( &(in_file->d_name[len-4]), ".lnk" ))) { + char shortcut_full[ MAXPATHLEN ]; + char dest_path[ MAXPATHLEN ]; char name[ MAXPATHLEN ]; time_t added; time_t accessed; wd_entity_t ent_type; + struct stat s; + int err; DEBUG_OUT("found file: %s",in_file->d_name); - strncpy( name, in_file->d_name, len-4 ); - - /* TODO */ - path[0] = 0; - added = -1; + dest_path[0] = 0; accessed = -1; + added = -1; ent_type = WD_ENTITY_UNKNOWN; - add_dir( ret_val, path, name, added, accessed, + strcpy( shortcut_full, path ); + strcat( shortcut_full, "\\" ); + strcat( shortcut_full, in_file->d_name ); + + err = stat( shortcut_full, &s); + if( err == -1 ) { + /* TODO */ + } else { + /* TODO: Are these really the appropriate attributes + to use? */ + added = s.st_ctime; + accessed = s.st_atime; + ResolveIt( NULL, shortcut_full, dest_path, + MAXPATHLEN ); + } + + strncpy( name, in_file->d_name, len-4 ); + name[len-4] = 0; + + + + add_dir( ret_val, dest_path, name, added, accessed, ent_type ); DEBUG_OUT("created new bookmark"); @@ -278,6 +303,8 @@ static dir_list_t load_dir_list_from_favourites( const config_container_t* const } } } + + CoUninitialize(); } return ret_val; } diff --git a/src/shrtcut.c b/src/shrtcut.c new file mode 100755 index 0000000..c17b412 --- /dev/null +++ b/src/shrtcut.c @@ -0,0 +1,151 @@ +/* These functions based on the code found at: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776891(v=vs.85).aspx#Shellink_Resolving_Shortcut + */ + +// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces +// to create and store a shortcut to the specified object. +// +// Returns the result of calling the member functions of the interfaces. +// +// Parameters: +// lpszPathObj - Address of a buffer that contains the path of the object, +// including the file name. +// lpszPathLink - Address of a buffer that contains the path where the +// Shell link is to be stored, including the file name. +// lpszDesc - Address of a buffer that contains a description of the +// Shell link, stored in the Comment field of the link +// properties. + +#if 0 +#include "stdafx.h" +#endif +#include "shlobj.h" +#include "windows.h" +#include "winnls.h" +#include "shobjidl.h" +#include "objbase.h" +#include "objidl.h" +#include "shlguid.h" + +HRESULT CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc) +{ + HRESULT hres; + IShellLink* psl; + + // Get a pointer to the IShellLink interface. It is assumed that CoInitialize + // has already been called. + hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl); + if (SUCCEEDED(hres)) + { + IPersistFile* ppf; + + // Set the path to the shortcut target and add the description. + psl->lpVtbl->SetPath(psl,lpszPathObj); + psl->lpVtbl->SetDescription(psl,lpszDesc); + + // Query IShellLink for the IPersistFile interface, used for saving the + // shortcut in persistent storage. + hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf); + + if (SUCCEEDED(hres)) + { + WCHAR wsz[MAX_PATH]; + + // Ensure that the string is Unicode. + MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); + + // Add code here to check return value from MultiByteWideChar + // for success. + + // Save the link by calling IPersistFile::Save. + hres = ppf->lpVtbl->Save(ppf,wsz, TRUE); + ppf->lpVtbl->Release(ppf); + } + psl->lpVtbl->Release(psl); + } + return hres; +} + +// ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces +// to retrieve the path and description from an existing shortcut. +// +// Returns the result of calling the member functions of the interfaces. +// +// Parameters: +// hwnd - A handle to the parent window. The Shell uses this window to +// display a dialog box if it needs to prompt the user for more +// information while resolving the link. +// lpszLinkFile - Address of a buffer that contains the path of the link, +// including the file name. +// lpszPath - Address of a buffer that receives the path of the link +// target, including the file name. +// lpszDesc - Address of a buffer that receives the description of the +// Shell link, stored in the Comment field of the link +// properties. + +HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath, int iPathBufferSize) +{ + HRESULT hres; + IShellLink* psl; + CHAR szGotPath[MAX_PATH]; + CHAR szDescription[MAX_PATH]; + WIN32_FIND_DATA wfd; + + *lpszPath = 0; // Assume failure + + // Get a pointer to the IShellLink interface. It is assumed that CoInitialize + // has already been called. + hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl); + if (SUCCEEDED(hres)) + { + IPersistFile* ppf; + + // Get a pointer to the IPersistFile interface. + hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (void**)&ppf); + + if (SUCCEEDED(hres)) + { + WCHAR wsz[MAX_PATH]; + + // Ensure that the string is Unicode. + MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH); + + // Add code here to check return value from MultiByteWideChar + // for success. + + // Load the shortcut. + hres = ppf->lpVtbl->Load(ppf,wsz, STGM_READ); + + if (SUCCEEDED(hres)) + { + // Resolve the link. + hres = psl->lpVtbl->Resolve(psl,hwnd, 0); + + if (SUCCEEDED(hres)) + { + // Get the path to the link target. + hres = psl->lpVtbl->GetPath(psl,szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); + + if (SUCCEEDED(hres)) + { + // Get the description of the target. + hres = psl->lpVtbl->GetDescription(psl,szDescription, MAX_PATH); + + if (SUCCEEDED(hres)) + { + /* TODO: Check success */ + strncpy(lpszPath, szGotPath, iPathBufferSize); + } + } + } + } + + // Release the pointer to the IPersistFile interface. + ppf->lpVtbl->Release(ppf); + } + + // Release the pointer to the IShellLink interface. + psl->lpVtbl->Release(psl); + } + return hres; +} + diff --git a/src/shrtcut.h b/src/shrtcut.h new file mode 100755 index 0000000..0bda2f0 --- /dev/null +++ b/src/shrtcut.h @@ -0,0 +1,6 @@ +#if !defined SHRTCUT_H +#define SHRTCUT_H + +extern HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath, int iPathBufferSize); + +#endif