efl/src/lib/evil/evil_link_xp.cpp

152 lines
3.2 KiB
C++
Raw Normal View History

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif /* HAVE_ERRNO_H */
* AUTHORS: * src/lib/Evil.h: * src/lib/Makefile.am: * src/lib/evil_inet.c: * src/lib/evil_mman.c: * src/lib/evil_stdio.c: * src/lib/evil_stdio.h: * src/lib/evil_stdlib.c: * src/lib/evil_util.c: * src/lib/sys/mman.h: * src/lib/evil_printa.c (added): * src/lib/evil_pformatw.c (added): * src/lib/evil_pformat.h (added): * src/lib/evil_printw.c (added): * src/lib/evil_print.h (added): * src/lib/evil_macro.h (added): * src/lib/evil_pformata.c (added): Add POSIX printf family. Code taken from the MinGW-w64 project and modified to be integrated into Evil. * src/bin/Makefile.am: * src/bin/evil_suite.c: * src/bin/evil_test_util.h (added): * src/bin/evil_test_print.c (added): * src/bin/evil_test_print.h (added): * src/bin/evil_test_util.c (added): Add util and printf unit tests * src/lib/evil_errno.c: * src/lib/errno.h (deleted): * src/lib/mingw32ce (added): * src/lib/mingw32ce/errno.h (added): Move errno.h for Windows CE in its own directory to suppress conflicts with standard errno.h when compiling for Windows XP. * src/lib/dlfcn/dlfcn.c: * src/lib/evil_link_ce.c: * src/lib/evil_main.c: * src/lib/evil_unistd.c: Define WIN32_LEAN_AND_MEAN only if it's not defined. * src/lib/evil_fcntl.c: Remove debug. * src/bin/evil_test_dlfcn.c: * src/bin/evil_test_environment.c: * src/bin/evil_test_gettimeofday.c: * src/bin/evil_test_link.c: * src/bin/evil_test_mkstemp.c: * src/bin/evil_test_pipe.c: * src/bin/evil_test_realpath.c: Remove warnings. * src/lib/evil_link_xp.cpp: Formatting. SVN revision: 68084
2012-02-17 12:48:11 -08:00
#include <shlobj.h>
#include <objidl.h>
#include <cstdio>
#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)
{
2012-07-20 00:38:40 -07:00
char fullname[PATH_MAX];
wchar_t *wnewpath;
IShellLink *pISL;
IPersistFile *pIPF;
HRESULT res;
size_t size;
realpath(oldpath, fullname);
res = CoInitialize(NULL);
if (FAILED(res))
{
if (res == E_OUTOFMEMORY)
errno = ENOMEM;
return -1;
}
if (FAILED(CoCreateInstance(CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void **)&pISL)))
goto no_instance;
if (FAILED(pISL->SetPath(fullname)))
goto no_setpath;
if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
goto no_queryinterface;
size = mbstowcs(NULL, newpath, 0);
wnewpath = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
if (!wnewpath)
goto malloc_failure;
if (mbstowcs(wnewpath, newpath, size + 1) == (size_t)(-1))
goto translation_failure;
if (FAILED(pIPF->Save(wnewpath, FALSE)))
goto no_save;
free(wnewpath);
pIPF->Release();
pISL->Release();
CoUninitialize();
return 0;
no_save:
translation_failure:
malloc_failure:
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 *wpath;
char new_path[PATH_MAX];
IShellLink *pISL;
IPersistFile *pIPF;
size_t length;
HRESULT res;
size_t size;
res = CoInitialize(NULL);
if (FAILED(res))
{
if (res == E_OUTOFMEMORY)
errno = ENOMEM;
return -1;
}
if (FAILED(CoCreateInstance(CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void **)&pISL)))
goto couninitialize;
if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
goto release_shell_link;
size = mbstowcs(NULL, path, 0);
wpath = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
if (!wpath)
goto release_persist_file;
mbstowcs(wpath, path, size + 1);
if (FAILED(pIPF->Load(wpath, STGM_READ)))
goto free_wpath;
if (FAILED(pISL->Resolve(NULL, SLR_UPDATE | SLR_NO_UI)))
goto free_wpath;
if (FAILED(pISL->GetPath(new_path, PATH_MAX, NULL, 0)))
goto free_wpath;
length = strlen(new_path);
if (length > bufsiz)
length = bufsiz;
memcpy(buf, new_path, length);
free(wpath);
pISL->Release();
pIPF->Release();
CoUninitialize();
return length;
free_wpath:
free(wpath);
release_persist_file:
pIPF->Release();
release_shell_link:
pISL->Release();
couninitialize:
CoUninitialize();
return -1;
}