|
15 | 15 | #include <unistd.h>
|
16 | 16 | #include <fcntl.h>
|
17 | 17 |
|
18 |
| -#ifdef WIN32 |
19 |
| - |
20 |
| -#include <winioctl.h> |
21 |
| - |
22 |
| -#define REPARSE_DATA_SIZE 1024 |
23 |
| - |
24 |
| -/* same layout as REPARSE_DATA_BUFFER, which is defined only in old winnt.h */ |
25 |
| -typedef struct REPARSE_DATA |
26 |
| -{ |
27 |
| - ULONG ReparseTag; |
28 |
| - WORD ReparseDataLength; |
29 |
| - WORD Reserved; |
30 |
| - union |
31 |
| - { |
32 |
| - struct |
33 |
| - { |
34 |
| - WORD SubstituteNameOffset; |
35 |
| - WORD SubstituteNameLength; |
36 |
| - WORD PrintNameOffset; |
37 |
| - WORD PrintNameLength; |
38 |
| - ULONG Flags; |
39 |
| - WCHAR PathBuffer[1]; |
40 |
| - } Symlink; |
41 |
| - struct |
42 |
| - { |
43 |
| - WORD SubstituteNameOffset; |
44 |
| - WORD SubstituteNameLength; |
45 |
| - WORD PrintNameOffset; |
46 |
| - WORD PrintNameLength; |
47 |
| - WCHAR PathBuffer[1]; |
48 |
| - } Mount; |
49 |
| - struct |
50 |
| - { |
51 |
| - BYTE DataBuffer[REPARSE_DATA_SIZE]; |
52 |
| - } Generic; |
53 |
| - }; |
54 |
| -} REPARSE_DATA; |
55 |
| - |
56 |
| -ssize_t |
57 |
| -readlink(const char *path, char *target, size_t size) |
58 |
| -{ |
59 |
| - HANDLE handle; |
60 |
| - DWORD attr; |
61 |
| - REPARSE_DATA data; |
62 |
| - DWORD datasize; |
63 |
| - PCWSTR wpath; |
64 |
| - int wlen; |
65 |
| - int r; |
66 |
| - |
67 |
| - attr = GetFileAttributes(path); |
68 |
| - if (attr == INVALID_FILE_ATTRIBUTES) |
69 |
| - { |
70 |
| - _dosmaperr(GetLastError()); |
71 |
| - return -1; |
72 |
| - } |
73 |
| - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) |
74 |
| - { |
75 |
| - errno = EINVAL; /* not a symlink */ |
76 |
| - return -1; |
77 |
| - } |
78 |
| - |
79 |
| - handle = CreateFileA(path, 0, |
80 |
| - FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, |
81 |
| - OPEN_EXISTING, |
82 |
| - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
83 |
| - if (handle == INVALID_HANDLE_VALUE) |
84 |
| - { |
85 |
| - _dosmaperr(GetLastError()); |
86 |
| - return -1; |
87 |
| - } |
88 |
| - |
89 |
| - wpath = NULL; |
90 |
| - if (DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, |
91 |
| - &data, sizeof(data), &datasize, NULL)) |
92 |
| - { |
93 |
| - switch (data.ReparseTag) |
94 |
| - { |
95 |
| - case IO_REPARSE_TAG_MOUNT_POINT: |
96 |
| - { |
97 |
| - wpath = data.Mount.PathBuffer + data.Mount.SubstituteNameOffset; |
98 |
| - wlen = data.Mount.SubstituteNameLength; |
99 |
| - break; |
100 |
| - } |
101 |
| - case IO_REPARSE_TAG_SYMLINK: |
102 |
| - { |
103 |
| - wpath = data.Symlink.PathBuffer + data.Symlink.SubstituteNameOffset; |
104 |
| - wlen = data.Symlink.SubstituteNameLength; |
105 |
| - break; |
106 |
| - } |
107 |
| - } |
108 |
| - } |
109 |
| - |
110 |
| - if (wpath == NULL) |
111 |
| - r = -1; |
112 |
| - else |
113 |
| - { |
114 |
| - if (wcsncmp(wpath, L"\\??\\", 4) == 0 || |
115 |
| - wcsncmp(wpath, L"\\\\?\\", 4) == 0) |
116 |
| - { |
117 |
| - wpath += 4; |
118 |
| - wlen -= 4; |
119 |
| - } |
120 |
| - r = WideCharToMultiByte(CP_ACP, 0, wpath, wlen, target, size, NULL, NULL); |
121 |
| - } |
122 |
| - |
123 |
| - CloseHandle(handle); |
124 |
| - return r; |
125 |
| -} |
126 |
| - |
127 |
| -#endif |
128 |
| - |
129 | 18 | #ifdef PGUT_FLOCK
|
130 | 19 |
|
131 | 20 | #ifdef WIN32
|
|
0 commit comments