win32: use unc paths

0.96
aCaB 16 years ago
parent e46b546ce3
commit 72c63093db
  1. 2
      shared/misc.c
  2. 24
      win32/compat/dirent.c
  3. 2
      win32/compat/libclamav_main.c
  4. 79
      win32/compat/w32_stat.c
  5. 3
      win32/compat/w32_stat.h
  6. 4
      win32/libclamav.vcproj

@ -319,7 +319,7 @@ int cfg_tcpsock(const struct optstruct *opts, struct sockaddr_in *tcpsock, in_ad
int cli_is_abspath(const char *path) {
#ifdef _WIN32
int len = strlen(path);
return (len > 2 && path[0] == '\\' && path[1] == '\\') || (len > 3 && path[1] == ':' && path[2] == '\\');
return (len > 2 && path[0] == '\\' && path[1] == '\\') || (len >= 2 && ((*path >= 'a' && *path <= 'z') || (*path >= 'A' && *path <= 'Z')) && path[1] == ':');
#else
return *path == '/';
#endif

@ -21,6 +21,7 @@
#include <errno.h>
#include "others.h"
#include "dirent.h"
#include "w32_stat.h"
#include "shared/misc.h"
DIR *opendir(const char *name) {
@ -28,11 +29,11 @@ DIR *opendir(const char *name) {
DWORD attrs;
int len;
struct stat sb;
wchar_t *wpath;
if(stat(name, &sb) < 0) {
errno = ENOENT; /* FIXME: should be set by stat() */
if(stat(name, &sb) < 0)
return NULL;
}
if(!S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
return NULL;
@ -41,19 +42,26 @@ DIR *opendir(const char *name) {
errno = ENOMEM;
return NULL;
}
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, d->entry, sizeof(d->entry) / sizeof(d->entry[0]));
if(!len || len >= PATH_MAX - 4) {
wpath = uncpath(name);
if(!wpath)
return NULL;
wcsncpy(d->entry, wpath, sizeof(d->entry) / sizeof(d->entry[0]));
free(wpath);
d->entry[sizeof(d->entry) / sizeof(d->entry[0])] = L'\0';
len = wcslen(d->entry);
if(len >= sizeof(d->entry) / sizeof(d->entry[0]) - 4) {
free(d);
errno = (len || (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ? ENAMETOOLONG : ENOENT;
errno = ENAMETOOLONG;
return NULL;
}
while(len) {
while(len--) {
if(d->entry[len] == L'\\')
d->entry[len] = L'\0';
else
break;
}
/* FIXME: this should be UNC'd */
wcsncat(d->entry, L"\\*.*", 4);
d->dh = INVALID_HANDLE_VALUE;
return d;

@ -100,7 +100,7 @@ void fix_paths(void) {
if(!have_ddir)
snprintf(_DATADIR, sizeof(_DATADIR), "%s\\database", dir);
if(!have_cdir) {
strncpy(_CONFDIR, dir, sizeof(_DATADIR));
strncpy(_CONFDIR, dir, sizeof(_CONFDIR));
have_cdir = 1;
}
}

@ -18,36 +18,73 @@
* MA 02110-1301, USA.
*/
#include <errno.h>
#include "others.h"
#include "shared/misc.h"
w32_stat(const char *path, struct stat *buf) {
int len = strlen(path) + 2;
wchar_t *wpath;
WIN32_FILE_ATTRIBUTE_DATA attrs;
if(len > PATH_MAX) {
errno = ENAMETOOLONG;
return -1;
}
if(!(wpath = cli_malloc(len * 2))) {
errno = ENOMEM;
return -1;
wchar_t *uncpath(const char *path) {
DWORD len = 0;
wchar_t *dest = cli_malloc((PATH_MAX + 1) * sizeof(wchar_t));
if(!dest)
return NULL;
if(strncmp(path, "\\\\", 2)) {
/* NOT already UNC */
memcpy(dest, L"\\\\?\\", 8);
if(!cli_is_abspath(path)) {
/* Relative path */
len = GetCurrentDirectoryW(PATH_MAX - 5, &dest[4]);
if(!len || len > PATH_MAX - 5) {
free(dest);
errno = (len || (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ? ENAMETOOLONG : ENOENT;
return NULL;
}
len += 4;
dest[len] = L'\\';
len++;
} else {
/* C:\ and friends */
len = 4;
}
} else {
/* UNC already */
len = 0;
}
/* FIXME: make it UNC */
if(!(len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, wpath, len))) {
errno = ENOENT;
free(wpath);
return -1;
if(!(len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, &dest[len], PATH_MAX - len)) || len > PATH_MAX - len) {
free(dest);
errno = (len || (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ? ENAMETOOLONG : ENOENT;
return NULL;
}
if((len == 3 || (len == 7 && !wcsncmp(wpath, L"\\\\?\\", 4))) && (wpath[len-2] == L':') &&
((wpath[len-3] >= L'A' && wpath[len-3] <= L'Z') || (wpath[len-3] >= L'a' && wpath[len-2] <= L'z')) ) {
/* stat drives as dirs */
wpath[len-1] = L'\\';
wpath[len] = L'\0';
len = wcslen(dest);
if(len == 6 && !wcsncmp(dest, L"\\\\?\\", 4) && (dest[5] == L':') && ((dest[4] >= L'A' && dest[4] <= L'Z') || (dest[4] >= L'a' && dest[4] <= L'z'))) {
dest[6] = L'\\';
dest[7] = L'\0';
}
return dest;
}
w32_stat(const char *path, struct stat *buf) {
int len;
wchar_t *wpath = uncpath(path);
WIN32_FILE_ATTRIBUTE_DATA attrs;
if(!wpath)
return -1;
len = wcslen(wpath);
if(len > 2 && wpath[len-1] == L'.' && wpath[len-2] == L'\\')
wpath[len-2] = L'\0'; /* windoze can't stat '.' ... */
len = GetFileAttributesExW(wpath, GetFileExInfoStandard, &attrs);
free(wpath);
if(!len) {
len = GetLastError();
errno = ENOENT;
return -1;
}

@ -39,4 +39,7 @@ int w32_stat(const char *path, struct stat *buf);
#define lstat stat
#define stat(path, buf) w32_stat(path, buf)
wchar_t *uncpath(const char *path);
#endif

@ -755,6 +755,10 @@
RelativePath="..\shared\getopt.c"
>
</File>
<File
RelativePath="..\shared\misc.c"
>
</File>
</Filter>
<Filter
Name="compat"

Loading…
Cancel
Save