/* **********************************************************
 * Copyright (c) 2007-2008 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Copyright (c) 2003-2007 Determina Corp. */
/* Copyright (c) 2002-2003 Massachusetts Institute of Technology */
/* Copyright (c) 2002 Hewlett-Packard Company */

// ShellInterface.cpp: implementation of the CShellInterface class.
//
//////////////////////////////////////////////////////////////////////

#ifndef DRSTATS_DEMO /* around whole file */

#include "stdafx.h"
#include "DynamoRIO.h"
#include "ShellInterface.h"

#include <shlobj.h>
#include <objbase.h>
#include <shlwapi.h>
#include <assert.h>


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CShellInterface::CShellInterface()
{

}

CShellInterface::~CShellInterface()
{

}

/*static */void CShellInterface::Initialize()
{
    if (m_bInitialized)
        return;
    int res = CoInitialize(NULL);
    assert(res == S_OK);
    m_bInitialized = TRUE;
}

/*static */void CShellInterface::Uninitialize()
{
    if (!m_bInitialized)
        return;
    CoUninitialize();
    m_bInitialized = FALSE;
}

/*static */BOOL CShellInterface::m_bInitialized = FALSE;

/*static */BOOL CShellInterface::ResolveLinkFile(TCHAR *name, TCHAR *resolution,
                                                 TCHAR *arguments, TCHAR *working_dir, HWND hwnd)
{
    assert(m_bInitialized);
    HRESULT hres;
    IShellLink* psl;
    WIN32_FIND_DATA wfd;

    *resolution = 0; // assume failure

    // 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)) {
#ifndef UNICODE
            WORD wsz [MAX_PATH]; // buffer for Unicode string

            // Ensure that the string consists of Unicode TCHARacters.
            MultiByteToWideChar(CP_ACP, 0, name, -1, wsz, MAX_PATH);
#else
            TCHAR *wsz = name;
#endif

            // 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)) {
                    _tcscpy(resolution, name);
                    // Get the path to the shortcut target.
                    hres = psl->GetPath(resolution, MAX_PATH,
                                        (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH);
                    if (! SUCCEEDED(hres))
                        goto cleanup;
                    hres = psl->GetArguments(arguments, MAX_PATH);
                    if (! SUCCEEDED(hres))
                        goto cleanup;
                    hres = psl->GetWorkingDirectory(working_dir, MAX_PATH);
                    if (! SUCCEEDED(hres))
                        goto cleanup;
                }
            }
        cleanup:
            // Release the pointer to IPersistFile.
            ppf->Release ();
        }
        // Release the pointer to IShellLink.
        psl->Release ();
    }
    return (SUCCEEDED(hres) ? TRUE : FALSE);
}



#if 0
// from "Shell Links" in MSDN library:
/*
The application-defined ResolveIt function in the following example
resolves a shortcut. Its parameters include a window handle, a pointer
to the path of the shortcut, and the address of a buffer that receives
the new path to the object. The window handle identifies the parent
window for any message boxes that the shell may need to display. For
example, the shell can display a message box if the link is on unshared
media, if network problems occur, if the user needs to insert a floppy
disk, and so on.

The ResolveIt function calls theCoCreateInstance function and assumes
that theCoInitialize function has already been called. Note that
ResolveIt needs to use theIPersistFile interface to store the link
information. IPersistFile is implemented by the IShellLink object. The
link information must be loaded before the path information is
retrieved, which is shown later in the example. Failing to load the link
information causes the calls to the IShellLink::GetPath and
IShellLink::GetDescription member functions to fail.
 */
HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath)
{
    HRESULT hres;
    IShellLink* psl;
    TCHAR szGotPath[MAX_PATH];
    TCHAR szDescription[MAX_PATH];
    WIN32_FIND_DATA wfd;

    *lpszPath = 0; // assume failure

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

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

            // Ensure that the string is Unicode.
            MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz,
                                MAX_PATH);

            // Load the shortcut.
            hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
            if (SUCCEEDED(hres)) {

                // Resolve the link.
                hres = psl->lpVtbl->Resolve(psl, hwnd, SLR_ANY_MATCH);
                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))
                        HandleErr(hres); // application-defined function

                    // Get the description of the target.
                    hres = psl->lpVtbl->GetDescription(psl,
                                                       szDescription, MAX_PATH);
                    if (!SUCCEEDED(hres))
                        HandleErr(hres);
                    lstrcpy(lpszPath, szGotPath);
                }
            }
            // Release the pointer to the IPersistFile interface.
            ppf->lpVtbl->Release(ppf);
        }
        // Release the pointer to the IShellLink interface.
        psl->lpVtbl->Release(psl);
    }
    return hres;
}

/* From MSDN's MFC sample:
"SHORTCUT: A SampleThat Manipulates Shortcuts"
*/

HRESULT CreateShortCut::CreateIt (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))
                AfxMessageBox ("SetPath failed!");

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

            if (! SUCCEEDED (hres))
                AfxMessageBox ("SetDescription failed!");

            // Ensure that the string consists of ANSI TCHARacters.
            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))
                AfxMessageBox ("Save failed!");

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


void ResolveShortCut::OnOK ()
{
    TCHAR szFile [MAX_PATH];

    // Get the selected item in the list box.
    DlgDirSelect (szFile, IDC_LIST1);

    // Find out whether it is a LNK file.
    if (_tcsstr (szFile, ".lnk") != NULL)
        // Make the call to ResolveShortcut::ResolveIt here.
        ResolveIt (m_hWnd, szFile);

    CDialog::OnOK ();
}

HRESULT ResolveShortCut::ResolveIt (HWND hwnd, LPCSTR pszShortcutFile)
{
    HRESULT hres;
    IShellLink *psl;
    TCHAR szGotPath [MAX_PATH];
    TCHAR szDescription [MAX_PATH];
    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 TCHARacters.
            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)) {
                    _tcscpy (szGotPath, pszShortcutFile);
                    // Get the path to the shortcut target.
                    hres = psl->GetPath (szGotPath, MAX_PATH,
                                         (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH);
                    if (! SUCCEEDED (hres))
                        AfxMessageBox ("GetPath failed!");
                    else
                        AfxMessageBox (szGotPath);
                    // Get the description of the target.
                    hres = psl->GetDescription (szDescription, MAX_PATH);
                    if (! SUCCEEDED (hres))
                        AfxMessageBox ("GetDescription failed!");
                    else
                        AfxMessageBox (szDescription);
                }
            }
            // Release the pointer to IPersistFile.
            ppf->Release ();
        }
        // Release the pointer to IShellLink.
        psl->Release ();
    }
    return hres;
}
#endif /* 0 */

#endif /* !DRSTATS_DEMO */ /* around whole file */
