* Makefile.in (DLL_OFILES): Drop shortcut.o.
* path.cc: Move all shortcut functions from shortcut.c to here. (check_shortcut): Implement without using COM interface. * path.h: Move definition of SHORTCUT_HDR_SIZE to here. * shortcut.c: Remove. * shortcut.h: Ditto.
This commit is contained in:
parent
c309557a9f
commit
03dc3df581
@ -1,3 +1,12 @@
|
|||||||
|
2002-09-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* Makefile.in (DLL_OFILES): Drop shortcut.o.
|
||||||
|
* path.cc: Move all shortcut functions from shortcut.c to here.
|
||||||
|
(check_shortcut): Implement without using COM interface.
|
||||||
|
* path.h: Move definition of SHORTCUT_HDR_SIZE to here.
|
||||||
|
* shortcut.c: Remove.
|
||||||
|
* shortcut.h: Ditto.
|
||||||
|
|
||||||
2002-09-03 Conrad Scott <conrad.scott@dsl.pipex.com>
|
2002-09-03 Conrad Scott <conrad.scott@dsl.pipex.com>
|
||||||
|
|
||||||
* fhandler.h (fhandler_socket::read): Remove method.
|
* fhandler.h (fhandler_socket::read): Remove method.
|
||||||
|
@ -132,7 +132,7 @@ DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o \
|
|||||||
malloc_wrapper.o miscfuncs.o mmap.o net.o ntea.o passwd.o path.o \
|
malloc_wrapper.o miscfuncs.o mmap.o net.o ntea.o passwd.o path.o \
|
||||||
pinfo.o pipe.o poll.o pthread.o regcomp.o regerror.o regexec.o \
|
pinfo.o pipe.o poll.o pthread.o regcomp.o regerror.o regexec.o \
|
||||||
regfree.o registry.o resource.o scandir.o sched.o sec_acl.o \
|
regfree.o registry.o resource.o scandir.o sched.o sec_acl.o \
|
||||||
sec_helper.o security.o select.o shared.o shm.o shortcut.o signal.o \
|
sec_helper.o security.o select.o shared.o shm.o signal.o \
|
||||||
sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o syscalls.o \
|
sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o syscalls.o \
|
||||||
sysconf.o syslog.o termios.o thread.o times.o tty.o uinfo.o uname.o \
|
sysconf.o syslog.o termios.o thread.o times.o tty.o uinfo.o uname.o \
|
||||||
v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o window.o \
|
v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o window.o \
|
||||||
|
@ -74,7 +74,6 @@ details. */
|
|||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "shortcut.h"
|
|
||||||
|
|
||||||
#ifdef _MT_SAFE
|
#ifdef _MT_SAFE
|
||||||
#define iteration _reent_winsup ()->_iteration
|
#define iteration _reent_winsup ()->_iteration
|
||||||
@ -105,6 +104,26 @@ struct symlink_info
|
|||||||
|
|
||||||
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
||||||
|
|
||||||
|
static char shortcut_header[SHORTCUT_HDR_SIZE];
|
||||||
|
static BOOL shortcut_initalized;
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_shortcut_header (void)
|
||||||
|
{
|
||||||
|
if (!shortcut_initalized)
|
||||||
|
{
|
||||||
|
shortcut_header[0] = 'L';
|
||||||
|
shortcut_header[4] = '\001';
|
||||||
|
shortcut_header[5] = '\024';
|
||||||
|
shortcut_header[6] = '\002';
|
||||||
|
shortcut_header[12] = '\300';
|
||||||
|
shortcut_header[19] = 'F';
|
||||||
|
shortcut_header[20] = '\f';
|
||||||
|
shortcut_header[60] = '\001';
|
||||||
|
shortcut_initalized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define CYGWIN_REGNAME (cygheap->cygwin_regname ?: CYGWIN_INFO_CYGWIN_REGISTRY_NAME)
|
#define CYGWIN_REGNAME (cygheap->cygwin_regname ?: CYGWIN_INFO_CYGWIN_REGISTRY_NAME)
|
||||||
|
|
||||||
/* Determine if path prefix matches current cygdrive */
|
/* Determine if path prefix matches current cygdrive */
|
||||||
@ -2696,6 +2715,68 @@ done:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
cmp_shortcut_header (const char *file_header)
|
||||||
|
{
|
||||||
|
create_shortcut_header ();
|
||||||
|
return memcmp (shortcut_header, file_header, SHORTCUT_HDR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_shortcut (const char *path, DWORD fileattr, HANDLE h,
|
||||||
|
char *contents, int *error, unsigned *pflags)
|
||||||
|
{
|
||||||
|
char file_header[SHORTCUT_HDR_SIZE];
|
||||||
|
unsigned short len;
|
||||||
|
int res = 0;
|
||||||
|
DWORD got = 0;
|
||||||
|
|
||||||
|
/* Valid Cygwin & U/WIN shortcuts are R/O. */
|
||||||
|
if (!(fileattr & FILE_ATTRIBUTE_READONLY))
|
||||||
|
goto file_not_symlink;
|
||||||
|
/* Read the files header information. This is used to check for a
|
||||||
|
Cygwin or U/WIN shortcut or later to check for executable files. */
|
||||||
|
if (!ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0))
|
||||||
|
{
|
||||||
|
*error = EIO;
|
||||||
|
goto close_it;
|
||||||
|
}
|
||||||
|
/* Check header if the shortcut is really created by Cygwin or U/WIN. */
|
||||||
|
if (got != SHORTCUT_HDR_SIZE || cmp_shortcut_header (file_header))
|
||||||
|
goto file_not_symlink;
|
||||||
|
/* Next 2 byte are USHORT, containing length of description entry. */
|
||||||
|
if (!ReadFile (h, &len, sizeof len, &got, 0))
|
||||||
|
{
|
||||||
|
*error = EIO;
|
||||||
|
goto close_it;
|
||||||
|
}
|
||||||
|
if (got != sizeof len || len == 0 || len > MAX_PATH)
|
||||||
|
goto file_not_symlink;
|
||||||
|
/* Now read description entry. */
|
||||||
|
if (!ReadFile (h, contents, len, &got, 0))
|
||||||
|
{
|
||||||
|
*error = EIO;
|
||||||
|
goto close_it;
|
||||||
|
}
|
||||||
|
if (got != len)
|
||||||
|
goto file_not_symlink;
|
||||||
|
contents[len] = '\0';
|
||||||
|
res = len;
|
||||||
|
if (res) /* It's a symlink. */
|
||||||
|
*pflags = PATH_SYMLINK;
|
||||||
|
goto close_it;
|
||||||
|
|
||||||
|
file_not_symlink:
|
||||||
|
/* Not a symlink, see if executable. */
|
||||||
|
if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (file_header, got))
|
||||||
|
*pflags |= PATH_EXEC;
|
||||||
|
|
||||||
|
close_it:
|
||||||
|
CloseHandle (h);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_sysfile (const char *path, DWORD fileattr, HANDLE h,
|
check_sysfile (const char *path, DWORD fileattr, HANDLE h,
|
||||||
char *contents, int *error, unsigned *pflags)
|
char *contents, int *error, unsigned *pflags)
|
||||||
|
@ -170,6 +170,9 @@ class path_conv
|
|||||||
/* Socket marker */
|
/* Socket marker */
|
||||||
#define SOCKET_COOKIE "!<socket >"
|
#define SOCKET_COOKIE "!<socket >"
|
||||||
|
|
||||||
|
/* The sizeof header written to a shortcut by Cygwin or U/WIN. */
|
||||||
|
#define SHORTCUT_HDR_SIZE 76
|
||||||
|
|
||||||
/* Maximum depth of symlinks (after which ELOOP is issued). */
|
/* Maximum depth of symlinks (after which ELOOP is issued). */
|
||||||
#define MAX_LINK_DEPTH 10
|
#define MAX_LINK_DEPTH 10
|
||||||
int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
|
int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
/* shortcut.c: Read shortcuts. This part of the code must be in C because
|
|
||||||
the C++ interface to COM doesn't work without -fvtable-thunk
|
|
||||||
which is too dangerous to use.
|
|
||||||
|
|
||||||
Copyright 2001 Red Hat, Inc.
|
|
||||||
|
|
||||||
This file is part of Cygwin.
|
|
||||||
|
|
||||||
This software is a copyrighted work licensed under the terms of the
|
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include "winsup.h"
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "shortcut.h"
|
|
||||||
|
|
||||||
/* TODO:
|
|
||||||
Currently duplicated from path.h. Later rearrangement of path.h
|
|
||||||
to allow including from plain C would be better. */
|
|
||||||
/* This is needed to avoid including path.h which is a pure C++ header. */
|
|
||||||
#define PATH_SYMLINK MOUNT_SYMLINK
|
|
||||||
#define PATH_EXEC MOUNT_EXEC
|
|
||||||
#define PATH_CYGWIN_EXEC MOUNT_CYGWIN_EXEC
|
|
||||||
#define PATH_ALL_EXEC (PATH_CYGWIN_EXEC | PATH_EXEC)
|
|
||||||
|
|
||||||
/* TODO: Ditto. */
|
|
||||||
static BOOL
|
|
||||||
has_exec_chars (const char *buf, int len)
|
|
||||||
{
|
|
||||||
return len >= 2 &&
|
|
||||||
((buf[0] == '#' && buf[1] == '!') ||
|
|
||||||
(buf[0] == ':' && buf[1] == '\n') ||
|
|
||||||
(buf[0] == 'M' && buf[1] == 'Z'));
|
|
||||||
}
|
|
||||||
|
|
||||||
char shortcut_header[SHORTCUT_HDR_SIZE];
|
|
||||||
BOOL shortcut_initalized;
|
|
||||||
|
|
||||||
void
|
|
||||||
create_shortcut_header (void)
|
|
||||||
{
|
|
||||||
if (!shortcut_initalized)
|
|
||||||
{
|
|
||||||
shortcut_header[0] = 'L';
|
|
||||||
shortcut_header[4] = '\001';
|
|
||||||
shortcut_header[5] = '\024';
|
|
||||||
shortcut_header[6] = '\002';
|
|
||||||
shortcut_header[12] = '\300';
|
|
||||||
shortcut_header[19] = 'F';
|
|
||||||
shortcut_header[20] = '\f';
|
|
||||||
shortcut_header[60] = '\001';
|
|
||||||
shortcut_initalized = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
cmp_shortcut_header (const char *file_header)
|
|
||||||
{
|
|
||||||
create_shortcut_header ();
|
|
||||||
return memcmp (shortcut_header, file_header, SHORTCUT_HDR_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_shortcut (const char *path, DWORD fileattr, HANDLE h,
|
|
||||||
char *contents, int *error, unsigned *pflags)
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
IShellLink *psl = NULL;
|
|
||||||
IPersistFile *ppf = NULL;
|
|
||||||
WCHAR wc_path[MAX_PATH];
|
|
||||||
char file_header[SHORTCUT_HDR_SIZE];
|
|
||||||
DWORD len = 0;
|
|
||||||
int res = 0;
|
|
||||||
DWORD got = 0;
|
|
||||||
|
|
||||||
/* Initialize COM library. */
|
|
||||||
CoInitialize (NULL);
|
|
||||||
|
|
||||||
/* Get a pointer to the IShellLink interface. */
|
|
||||||
hres = CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
|
||||||
&IID_IShellLink, (void **)&psl);
|
|
||||||
if (FAILED (hres))
|
|
||||||
goto close_it;
|
|
||||||
/* Get a pointer to the IPersistFile interface. */
|
|
||||||
hres = psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile, (void **)&ppf);
|
|
||||||
if (FAILED (hres))
|
|
||||||
goto close_it;
|
|
||||||
/* Load the shortcut. */
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, path, -1, wc_path, MAX_PATH);
|
|
||||||
hres = ppf->lpVtbl->Load (ppf, wc_path, STGM_READ);
|
|
||||||
if (FAILED (hres))
|
|
||||||
goto close_it;
|
|
||||||
/* Read the files header information. This is used to check for a
|
|
||||||
Cygwin or U/WIN shortcut or later to check for executable files. */
|
|
||||||
if (!ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0))
|
|
||||||
{
|
|
||||||
*error = EIO;
|
|
||||||
goto close_it;
|
|
||||||
}
|
|
||||||
/* Try the description (containing a POSIX path) first. */
|
|
||||||
if (fileattr & FILE_ATTRIBUTE_READONLY)
|
|
||||||
{
|
|
||||||
/* Check header if the shortcut is really created by Cygwin or U/WIN. */
|
|
||||||
if (got == SHORTCUT_HDR_SIZE && !cmp_shortcut_header (file_header))
|
|
||||||
{
|
|
||||||
hres = psl->lpVtbl->GetDescription (psl, contents, MAX_PATH);
|
|
||||||
if (FAILED (hres))
|
|
||||||
goto file_not_symlink;
|
|
||||||
len = strlen (contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if TREAT_NATIVE_SHORTCUTS_AS_SYMLINKS
|
|
||||||
/* No description or not R/O: Check the "official" path. */
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
char full_path[MAX_PATH];
|
|
||||||
WIN32_FIND_DATA wfd;
|
|
||||||
|
|
||||||
/* Convert to full path (easy way) */
|
|
||||||
if ((path[0] == '\\' && path[1] == '\\')
|
|
||||||
|| (_toupper (path[0]) >= 'A' && _toupper (path[0]) <= 'Z'
|
|
||||||
&& path[1] == ':'))
|
|
||||||
len = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
len = GetCurrentDirectory (MAX_PATH, full_path);
|
|
||||||
if (path[0] == '\\')
|
|
||||||
len = 2;
|
|
||||||
else if (full_path[len - 1] != '\\')
|
|
||||||
strcpy (full_path + len++, "\\");
|
|
||||||
}
|
|
||||||
strcpy (full_path + len, path);
|
|
||||||
/* Set relative path inside of IShellLink interface. */
|
|
||||||
hres = psl->lpVtbl->SetRelativePath (psl, full_path, 0);
|
|
||||||
if (FAILED (hres))
|
|
||||||
goto file_not_symlink;
|
|
||||||
/* Get the path to the shortcut target. */
|
|
||||||
hres = psl->lpVtbl->GetPath (psl, contents, MAX_PATH, &wfd, 0);
|
|
||||||
if (FAILED(hres))
|
|
||||||
goto file_not_symlink;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
res = strlen (contents);
|
|
||||||
if (res) /* It's a symlink. */
|
|
||||||
*pflags = PATH_SYMLINK;
|
|
||||||
goto close_it;
|
|
||||||
|
|
||||||
file_not_symlink:
|
|
||||||
/* Not a symlink, see if executable. */
|
|
||||||
if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (file_header, got))
|
|
||||||
*pflags |= PATH_EXEC;
|
|
||||||
|
|
||||||
close_it:
|
|
||||||
/* Release the pointer to IPersistFile. */
|
|
||||||
if (ppf)
|
|
||||||
ppf->lpVtbl->Release(ppf);
|
|
||||||
/* Release the pointer to IShellLink. */
|
|
||||||
if (psl)
|
|
||||||
psl->lpVtbl->Release(psl);
|
|
||||||
/* Uninitialize COM library. */
|
|
||||||
CoUninitialize ();
|
|
||||||
CloseHandle (h);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/* shortcut.h: Header file for shortcut.c
|
|
||||||
|
|
||||||
Copyright 2001 Red Hat, Inc.
|
|
||||||
|
|
||||||
This file is part of Cygwin.
|
|
||||||
|
|
||||||
This software is a copyrighted work licensed under the terms of the
|
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The header written to a shortcut by Cygwin or U/WIN. */
|
|
||||||
#define SHORTCUT_HDR_SIZE 76
|
|
||||||
|
|
||||||
extern char shortcut_header[];
|
|
||||||
extern BOOL shortcut_initalized;
|
|
||||||
|
|
||||||
extern void create_shortcut_header ();
|
|
||||||
|
|
||||||
int check_shortcut (const char *path, DWORD fileattr, HANDLE h,
|
|
||||||
char *contents, int *error, unsigned *pflags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
};
|
|
||||||
#endif
|
|
Loading…
x
Reference in New Issue
Block a user