// Resolves and creates shell links.
//
// Dependencies: MessageLastError (discardable)
// Status: unchecked
//
// Web: http://unclassified.software/source/shelllink

// maybe we need these includes
#include <shlobj.h>
#include <objbase.h>

HRESULT ShellResolveLink(HWND hwnd,
                         LPCSTR pszShortcutFile,
                         char *szGotPath,
                         char *szDescription)
{
	HRESULT hres;
	IShellLink *psl;
	WIN32_FIND_DATA wfd;

	// Get a pointer to the IShellLink interface.
	hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
	                        IID_IShellLink, (void **) &psl);
	if (SUCCEEDED(hres))
	{
		IPersistFile *ppf;

		// Get a pointer to the IPersistFile interface.
		hres = psl->QueryInterface(IID_IPersistFile, (void **) &ppf);
		if (SUCCEEDED(hres))
		{
			WORD wsz[MAX_PATH];   // buffer for Unicode string

			// Ensure that the string consists of Unicode characters.
			MultiByteToWideChar(CP_ACP, 0, pszShortcutFile, -1, wsz, MAX_PATH);

			// Load the shortcut.
			hres = ppf->Load(wsz, STGM_READ);
			if (SUCCEEDED(hres))
			{
				// Resolve the shortcut.
				hres = psl->Resolve(hwnd, SLR_ANY_MATCH);

				if (SUCCEEDED(hres))
				{
					strcpy(szGotPath, pszShortcutFile);
					// Get the path to the shortcut target.
					hres = psl->GetPath(szGotPath, MAX_PATH,
					                    (WIN32_FIND_DATA *) &wfd, SLGP_SHORTPATH);
					// Get the description of the target.
					hres = psl->GetDescription(szDescription, MAX_PATH);
				}
			}
			// Release the pointer to IPersistFile.
			ppf->Release();
		}
		// Release the pointer to IShellLink.
		psl->Release();
	}
	return hres;
}

HRESULT ShellCreateLink(LPCSTR pszShortcutFile, LPSTR pszLink, LPSTR pszDesc)
{
	HRESULT hres;
	IShellLink *psl;

	// Create an IShellLink object and get a pointer to the IShellLink
	// interface (returned from CoCreateInstance).
	hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
	                        IID_IShellLink, (void **) &psl);
	if (SUCCEEDED(hres))
	{
		IPersistFile *ppf;

		// Query IShellLink for the IPersistFile interface for
		// saving the shortcut in persistent storage.
		hres = psl->QueryInterface(IID_IPersistFile, (void **) &ppf);
		if (SUCCEEDED(hres))
		{
			WORD wsz[MAX_PATH];   // buffer for Unicode string

			// Set the path to the shortcut target.
			hres = psl->SetPath(pszShortcutFile);

			if (!SUCCEEDED(hres))
			{
				MessageLastError("CreateLink(SetPath)");
			}

			// Set the description of the shortcut.
			hres = psl->SetDescription(pszDesc);

			if (!SUCCEEDED(hres))
			{
				MessageLastError("CreateLink(SetDescription)");
			}

			// Ensure that the string consists of ANSI characters.
			MultiByteToWideChar(CP_ACP, 0, pszLink, -1, wsz, MAX_PATH);

			// Save the shortcut via the IPersistFile::Save member function.
			hres = ppf->Save(wsz, TRUE);

			if (!SUCCEEDED(hres))
			{
				MessageLastError("CreateLink(Save)");
			}

			// Release the pointer to IPersistFile.
			ppf->Release();
		}
		// Release the pointer to IShellLink.
		psl->Release();
	}
	return(hres);
}
