Skip to content

Commit

Permalink
Updates #12 by reading information from the bookmark links
Browse files Browse the repository at this point in the history
  • Loading branch information
bright-tools committed Dec 13, 2013
1 parent b4a8b39 commit 0f7bb77
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/cmdln.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
43 changes: 35 additions & 8 deletions src/dir_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <shlobj.h>
#include <dirent.h>
static dir_list_t load_dir_list_from_favourites( const config_container_t* const p_config, const char* const p_fn )
Expand All @@ -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;
Expand All @@ -251,33 +255,56 @@ 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");
}
}
}
}

CoUninitialize();
}
return ret_val;
}
Expand Down
151 changes: 151 additions & 0 deletions src/shrtcut.c
Original file line number Diff line number Diff line change
@@ -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;
}

6 changes: 6 additions & 0 deletions src/shrtcut.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#if !defined SHRTCUT_H
#define SHRTCUT_H

extern HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath, int iPathBufferSize);

#endif

0 comments on commit 0f7bb77

Please sign in to comment.