* src/bin/evil_test_gettimeofday.c:

add output
	* src/bin/evil_test_link.c:
	add a unit test for readlink()
	* src/lib/evil_link_xp.cpp:
	fix readlink() and symlink() on Windows XP



SVN revision: 38070
This commit is contained in:
Vincent Torri 2008-12-09 22:27:53 +00:00
parent dd4a299895
commit 26d595d0d8
4 changed files with 145 additions and 43 deletions

View File

@ -1,3 +1,14 @@
2008-12-09 Vincent Torri <doursse at users dot sf dot net>
* src/bin/evil_test_gettimeofday.c:
add output
* src/bin/evil_test_link.c:
add a unit test for readlink()
* src/lib/evil_link_xp.cpp:
fix readlink() and symlink() on Windows XP
2008-12-05 Vincent Torri <doursse at users dot sf dot net>
* src/lib/evil_main.c:

View File

@ -25,6 +25,7 @@ test_time_tests_run(suite *s)
printf ("time : %ld %ld\n", tp1.tv_sec, tp1.tv_usec);
printf ("time : %ld %ld\n", tp2.tv_sec, tp2.tv_usec);
printf ("time : %f\n", (double)tp2.tv_sec - tp1.tv_sec + (tp2.tv_usec - tp1.tv_usec) / 1000000.0);
return 1;
}

View File

@ -38,15 +38,90 @@ test_link_test_file_create(const char *name, const char *data)
static int
test_link_test_symlink(void)
{
int res;
if (!test_link_test_file_create("evil_test_link.dat",
"evil_test_link symlink data\n"))
return 0;
if (symlink("evil_test_link.dat", "evil_test_link") < 0)
if (symlink("evil_test_link.dat", "evil_test_link.lnk") < 0)
{
unlink("evil_test_link.dat");
return 0;
}
if (unlink("evil_test_link.lnk") < 0)
{
unlink("evil_test_link.dat");
return 0;
}
if (unlink("evil_test_link.dat") < 0)
return 0;
return 1;
}
static int
test_link_test_readlink(void)
{
char buf[1024];
char *data;
FILE *f;
ssize_t s1;
size_t s2;
int l;
data = "evil_test_link symlink data\n";
if (!test_link_test_file_create("evil_test_link.dat", data))
return 0;
if (symlink("evil_test_link.dat", "evil_test_link.lnk") < 0)
return 0;
if ((s1 = readlink("evil_test_link.lnk", buf, 1023)) < 0)
{
unlink("evil_test_link.dat");
unlink("evil_test_link.lnk");
return 0;
}
buf[s1] = '\0';
f = fopen(buf, "rb");
if (!f)
{
unlink("evil_test_link.dat");
unlink("evil_test_link.lnk");
return 0;
}
l = strlen(data);
s2 = fread(buf, 1, l + 1, f);
if ((int)s2 != (l + 1))
{
fclose(f);
unlink("evil_test_link.dat");
unlink("evil_test_link.lnk");
return 0;
}
if (strcmp(buf, data))
{
fclose(f);
unlink("evil_test_link.dat");
unlink("evil_test_link.lnk");
return 0;
}
fclose(f);
if (unlink("evil_test_link.lnk") < 0)
{
unlink("evil_test_link.dat");
return 0;
}
if (unlink("evil_test_link.dat") < 0)
return 0;
@ -56,7 +131,12 @@ test_link_test_symlink(void)
static int
test_link_tests_run(suite *s)
{
return test_link_test_symlink();
int res;
res = test_link_test_symlink();
res &= test_link_test_readlink();
return res;
}
int

View File

@ -9,6 +9,7 @@
# include <shlobj.h>
# include <objidl.h>
#include <cstdio>
#include "Evil.h"
@ -24,12 +25,11 @@
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;
wchar_t *wnewpath;
IShellLink *pISL;
IPersistFile *pIPF;
HRESULT res;
size_t size;
res = CoInitialize(NULL);
if (FAILED(res))
@ -39,27 +39,29 @@ symlink(const char *oldpath, const char *newpath)
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)))
(void **)&pISL)))
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)))
if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
goto no_queryinterface;
mbstowcs(new_path, newpath, MB_CUR_MAX);
if (FAILED(pIPF->Save(new_path, FALSE)))
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();
@ -67,6 +69,8 @@ symlink(const char *oldpath, const char *newpath)
return 0;
no_save:
translation_failure:
malloc_failure:
pIPF->Release();
no_queryinterface:
no_setpath:
@ -79,14 +83,13 @@ symlink(const char *oldpath, const char *newpath)
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;
wchar_t *wpath;
char new_path[PATH_MAX];
IShellLink *pISL;
IPersistFile *pIPF;
unsigned int length;
HRESULT res;
size_t size;
res = CoInitialize(NULL);
if (FAILED(res))
@ -96,25 +99,30 @@ readlink(const char *path, char *buf, size_t bufsiz)
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;
IID_IShellLink,
(void **)&pISL)))
goto couninitialize;
mbstowcs(old_path, path, MB_CUR_MAX);
if (FAILED(pIPF->Load(old_path, STGM_READWRITE)))
goto no_load;
if (FAILED(pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF)))
goto release_shell_link;
shell_link = &pISL;
if (FAILED(pIPF->QueryInterface(IID_IShellLink, (void **)shell_link)))
goto no_queryinterface;
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 no_getpath;
goto free_wpath;
length = strlen(new_path);
if (length > bufsiz)
@ -122,18 +130,20 @@ readlink(const char *path, char *buf, size_t bufsiz)
memcpy(buf, new_path, length);
free(wpath);
pISL->Release();
pIPF->Release();
CoUninitialize();
return length;
no_getpath:
pISL->Release();
no_queryinterface:
no_load:
free_wpath:
free(wpath);
release_persist_file:
pIPF->Release();
no_instance:
release_shell_link:
pISL->Release();
couninitialize:
CoUninitialize();
return -1;
}