Solved

How can I retreive the location that a symbolic link points to on Windows?

Posted on 2006-07-06
10
302 Views
Last Modified: 2012-06-27
Hello,

I need to get the canonical form of a path. To do so, I need to resolve symbolic links if some are found in the input path. On unix, I used lstat() to see if the dirrectory or the file is a symbolic link, if so then I use readlink() to get the location that the link points to.

Now I need to implement the same thing on Windows, but I can't find how I can get this information about a symbolic link.

Please Help!

Thanks,

Phelippe
0
Comment
Question by:pcigeomatics
10 Comments
 
LVL 5

Expert Comment

by:bastibartel
ID: 17052894
From MSDN:


HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath)
{
    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.
    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;
}

Cheers,
Sebastian
0
 
LVL 15

Accepted Solution

by:
lakshman_ce earned 63 total points
ID: 17052907
You can try to use the CopyFile and CopyFileEx methods of Win32 API
You can read more at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/Symbolic_Link_Effects_on_File_Systems_Functions.asp
0
 
LVL 5

Expert Comment

by:bastibartel
ID: 17052911
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:pcigeomatics
ID: 17053466
The ResolveIt() functions seems to be doing what I want, but I don't have access to a HWND...

The CopyFile() or CopyFileEx() functions are not what I'm looking for.

The IShellLink::GetPath() method looks like could do the work, but hurray for Windows documentation, I have no clue how to create the object or what files to include.

I tried this with no success;

WIN32_FIND_DATA sFindData;

HANDLE hFindHandle = FindFirstFile("C:\\temp\\demo", &sFindData); // C:\temp\demo is a link to C:\home\demo

if (hFindHandle != INVALID_HANDLE_VALUE)
{
    FindClose(hFindHandle);

    char szResolvePath[MAX_PATH];

    HRESULT hResult = IShellLink::GetPath(szResolvePath, MAX_PATH, &sFindData, SLGP_UNCPRIORITY);

    if (hResult == NOERROR)
    {
        printf("Resolved Path: %s\n", szResolvePath);
    }
}

I get these errors;

c:\Temp\Testl\Test.cpp(40) : error C2653: 'IShellLink' : is not a class or namespace name
c:\Temp\Test\Test.cpp(41) : error C2065: 'SLGP_UNCPRIORITY' : undeclared identifier

Phelippe
0
 
LVL 5

Expert Comment

by:bastibartel
ID: 17054590
Hi there,

Try including  "shlobj.h2
For the HWND you may pass any Window Handle you like. It is for any message boxes that the shell may need to popup.

Cheers Sebastian
0
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 62 total points
ID: 17054973
Here's a slightly more concise version of the same sequence, including the various prerequisites, such as the #include and the call to CoInitialize.   It is from here:

       How to create and resolve a shortcut
       http://www.codeproject.com/shell/create_shortcut.asp

#include <atlbase.h>

HRESULT ResolveShortcut(/*in*/ LPCTSTR lpszShortcutPath,
                        /*out*/ LPTSTR lpszFilePath)
{
    HRESULT hRes = E_FAIL;
    CComPtr<IShellLink> ipShellLink;
    TCHAR szPath[MAX_PATH];    
    WIN32_FIND_DATA wfd;    
    WCHAR wszTemp[MAX_PATH];

    lpszFilePath[0] = '\0';

    hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                            IID_IShellLink, (void**)&ipShellLink
      );
    if (SUCCEEDED(hRes)) {
        CComQIPtr<IPersistFile> ipPersistFile(ipShellLink);
        MultiByteToWideChar(CP_ACP, 0, lpszShortcutPath, -1, wszTemp, MAX_PATH);

        hRes = ipPersistFile->Load(wszTemp, STGM_READ);
        if (SUCCEEDED(hRes)) {
            hRes = ipShellLink->Resolve(NULL, SLR_UPDATE);
            if (SUCCEEDED(hRes)) {
                hRes = ipShellLink->GetPath(szPath, MAX_PATH, &wfd, SLGP_RAWPATH);
                if (FAILED(hRes)) {
                    return hRes;
                        }
                lstrcpyn( lpszFilePath, szPath, MAX_PATH );
            }
        }
    }
    return hRes;
}

void CD35Dlg::OnButton2()
{
    CoInitialize(0);

    char lpszShortcutPath[] = "C:\\Documents and Settings\\Dan\\Desktop\\Imaging.lnk";
    char szFilePath[MAX_PATH];

    ResolveShortcut( lpszShortcutPath, szFilePath );
    CoUninitialize( );      
}
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 17208756
I recommend: split to lakshman_ce and DanRollins
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now