efl/legacy/evil/src/lib/evil_link_xp.cpp

140 lines
3.0 KiB
C++

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif /* HAVE_ERRNO_H */
# include <shlobj.h>
# include <objidl.h>
#include "Evil.h"
/*
* Symbolic links and directory related functions
*
*/
/* REMARK: Windows has no symbolic link. */
/* Nevertheless, it can create and read .lnk files */
int
symlink(const char *oldpath, const char *newpath)
{
wchar_t new_path[MB_CUR_MAX];
IShellLink *pISL;
IShellLink **shell_link;
IPersistFile *pIPF;
IPersistFile **persit_file;
HRESULT res;
res = CoInitialize(NULL);
if (FAILED(res))
{
if (res == E_OUTOFMEMORY)
errno = ENOMEM;
return -1;
}
/* Hack to cleanly remove a warning */
shell_link = &pISL;
if (FAILED(CoCreateInstance(CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void **)shell_link)))
goto no_instance;
if (FAILED(pISL->SetPath(oldpath)))
goto no_setpath;
/* Hack to cleanly remove a warning */
persit_file = &pIPF;
if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)persit_file)))
goto no_queryinterface;
mbstowcs(new_path, newpath, MB_CUR_MAX);
if (FAILED(pIPF->Save(new_path, FALSE)))
goto no_save;
pIPF->Release();
pISL->Release();
CoUninitialize();
return 0;
no_save:
pIPF->Release();
no_queryinterface:
no_setpath:
pISL->Release();
no_instance:
CoUninitialize();
return -1;
}
ssize_t
readlink(const char *path, char *buf, size_t bufsiz)
{
wchar_t old_path[MB_CUR_MAX];
char new_path[PATH_MAX];
IShellLink *pISL;
IShellLink **shell_link;
IPersistFile *pIPF;
IPersistFile **persit_file;
unsigned int length;
HRESULT res;
res = CoInitialize(NULL);
if (FAILED(res))
{
if (res == E_OUTOFMEMORY)
errno = ENOMEM;
return -1;
}
/* Hack to cleanly remove a warning */
persit_file = &pIPF;
if (FAILED(CoCreateInstance(CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPersistFile,
(void **)persit_file)))
goto no_instance;
mbstowcs(old_path, path, MB_CUR_MAX);
if (FAILED(pIPF->Load(old_path, STGM_READWRITE)))
goto no_load;
shell_link = &pISL;
if (FAILED(pIPF->QueryInterface(IID_IShellLink, (void **)shell_link)))
goto no_queryinterface;
if (FAILED(pISL->GetPath(new_path, PATH_MAX, NULL, 0)))
goto no_getpath;
length = strlen(new_path);
if (length > bufsiz)
length = bufsiz;
memcpy(buf, new_path, length);
pISL->Release();
pIPF->Release();
CoUninitialize();
return length;
no_getpath:
pISL->Release();
no_queryinterface:
no_load:
pIPF->Release();
no_instance:
CoUninitialize();
return -1;
}