Fossil

Check-in [631dff61e0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Make everything compile on MinGW(-w64). WARNING: will not run on Windows XP, that still has to be fixed! Should work on Vista+.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | winsymlink
Files: files | file ages | folders
SHA1: 631dff61e0e8e1875c3f5a5a78bf5d946473c217
User & Date: jan.nijtmans 2014-09-26 09:23:37.180
Context
2014-09-29
09:46
Merge trunk. Style changes. Implement fallback in case of Windows XP. check-in: f2ba1d2233 user: jan.nijtmans tags: winsymlink
2014-09-26
09:23
Make everything compile on MinGW(-w64). WARNING: will not run on Windows XP, that still has to be fixed! Should work on Vista+. check-in: 631dff61e0 user: jan.nijtmans tags: winsymlink
2014-09-25
19:21
Summary: a number of changes to improve windows symlink handling. Detail: fixed file_contains_merge_marker failure on windows symlinks; fixed inadequate S_ISLNK macro for windows; backed out change made to revert query ("OR islink" removed); added special processing to vfile_check_signature for windows symlink type changes; fixed a few flaws in the windows specific posix-compatibility routines to improve symlink handling. check-in: 9c5bbd6a01 user: sdr tags: winsymlink
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/file.c.
70
71
72
73
74
75
76



77
78
79
80
81
82
83
/*
** On Windows S_ISLNK can be true or false.
*/
/* the S_ISLNK provided by dirent.h for windows is inadequate, so fix it */
#if defined(S_ISLNK)
# undef S_ISLNK
#endif



#if !defined(S_ISLNK)
# define S_ISLNK(x) ((x)==S_IFLNK)
#endif
#endif

static int fileStatValid = 0;
static struct fossilStat fileStat;







>
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
** On Windows S_ISLNK can be true or false.
*/
/* the S_ISLNK provided by dirent.h for windows is inadequate, so fix it */
#if defined(S_ISLNK)
# undef S_ISLNK
#endif
#if !defined(S_IFLNK)
# define S_IFLNK 0120000
#endif
#if !defined(S_ISLNK)
# define S_ISLNK(x) ((x)==S_IFLNK)
#endif
#endif

static int fileStatValid = 0;
static struct fossilStat fileStat;
Changes to src/winfile.c.
19
20
21
22
23
24
25
26
27







28
29
30
31
32






33

34

35
36
37
38
39
40
41
** on Windows using the Win32 API.
*/
#include "config.h"
#ifdef _WIN32
/* This code is for win32 only */
#include <sys/stat.h>
#include <windows.h>
#include <versionhelpers.h>
#include "winfile.h"








#ifndef LABEL_SECURITY_INFORMATION
#   define LABEL_SECURITY_INFORMATION (0x00000010L)
#endif







/* a couple defines to make the borrowed struct below compile */

#define _ANONYMOUS_UNION

#define DUMMYUNIONNAME

/*
** this structure copied on 20 Sept 2014 from
** https://reactos-mirror.googlecode.com/svn-history/r54752/branches/usb-bringup/include/ddk/ntifs.h
** which is a public domain file from the ReactOS DDK package.
*/







<

>
>
>
>
>
>
>





>
>
>
>
>
>

>
|
>







19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
** on Windows using the Win32 API.
*/
#include "config.h"
#ifdef _WIN32
/* This code is for win32 only */
#include <sys/stat.h>
#include <windows.h>

#include "winfile.h"

#if !defined(S_IFLNK)
# define S_IFLNK 0120000
#endif
#if !defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
# define SYMBOLIC_LINK_FLAG_DIRECTORY (0x1)
#endif

#ifndef LABEL_SECURITY_INFORMATION
#   define LABEL_SECURITY_INFORMATION (0x00000010L)
#endif

#if defined(__MSVCRT__)
/* TODO: determine those dynamically. */
WINBASEAPI DWORD WINAPI GetFinalPathNameByHandleW (HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags);
WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkW (LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags);
#endif

/* a couple defines to make the borrowed struct below compile */
#ifndef _ANONYMOUS_UNION
# define _ANONYMOUS_UNION
#endif
#define DUMMYUNIONNAME

/*
** this structure copied on 20 Sept 2014 from
** https://reactos-mirror.googlecode.com/svn-history/r54752/branches/usb-bringup/include/ddk/ntifs.h
** which is a public domain file from the ReactOS DDK package.
*/
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
** creation of a text file with the context of the link.
** Returns 0 on success, 1 on failure.
*/
int win32_symlink(const char *oldpath, const char *newpath){
  fossilStat stat;
  int created = 0;
  DWORD flags = 0;
  wchar_t *zMbcs;

  /* does oldpath exist? is it a dir or a file? */  
  zMbcs = fossil_utf8_to_filename(oldpath);
  if (win32_stat(zMbcs, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
  }
  fossil_filename_free(zMbcs);

  /* remove newpath before creating the symlink */
  zMbcs = fossil_utf8_to_filename(newpath);
  win32_unlink_rmdir(zMbcs);

  fossil_filename_free(zMbcs);

  created = CreateSymbolicLink(newpath, oldpath, flags);

  /* if the symlink was not created, create a plain text file */
  if (!created){
    Blob content;
    blob_set(&content, oldpath);
    blob_write_to_file(&content, newpath);
    blob_reset(&content);







|


|
|



<




>

|
<







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283

284
285
286
287
288
289
290
** creation of a text file with the context of the link.
** Returns 0 on success, 1 on failure.
*/
int win32_symlink(const char *oldpath, const char *newpath){
  fossilStat stat;
  int created = 0;
  DWORD flags = 0;
  wchar_t *zMbcs, *zMbcsOld;

  /* does oldpath exist? is it a dir or a file? */  
  zMbcsOld = fossil_utf8_to_filename(oldpath);
  if (win32_stat(zMbcsOld, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
  }


  /* remove newpath before creating the symlink */
  zMbcs = fossil_utf8_to_filename(newpath);
  win32_unlink_rmdir(zMbcs);
  created = CreateSymbolicLinkW(zMbcs, zMbcsOld, flags);
  fossil_filename_free(zMbcs);
  fossil_filename_free(zMbcsOld);


  /* if the symlink was not created, create a plain text file */
  if (!created){
    Blob content;
    blob_set(&content, oldpath);
    blob_write_to_file(&content, newpath);
    blob_reset(&content);
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  wchar_t *pFilename;
  wchar_t fullName[MAX_PATH+1];
  DWORD fullLength;
  wchar_t volName[MAX_PATH+1];
  DWORD fsFlags;

  /* symlinks only supported on vista or greater */
  if (!IsWindowsVistaOrGreater())
    return 0;
  
  /* next we need to check to see if the privilege is available */
  
  /* can't check privilege if we can't lookup its value */
  if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
    return 0;
  
  /* can't check privilege if we can't open the process token */







|
|
|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  wchar_t *pFilename;
  wchar_t fullName[MAX_PATH+1];
  DWORD fullLength;
  wchar_t volName[MAX_PATH+1];
  DWORD fsFlags;

  /* symlinks only supported on vista or greater */
  /* if (!IsWindowsVistaOrGreater())  //  TODO: make it work on MinGW
    return 0; */

  /* next we need to check to see if the privilege is available */
  
  /* can't check privilege if we can't lookup its value */
  if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
    return 0;
  
  /* can't check privilege if we can't open the process token */