xref: /reactos/base/services/nfsd/util.h (revision c2c66aff)
1 /* NFSv4.1 client for Windows
2  * Copyright � 2012 The Regents of the University of Michigan
3  *
4  * Olga Kornievskaia <aglo@umich.edu>
5  * Casey Bodley <cbodley@umich.edu>
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * without any warranty; without even the implied warranty of merchantability
14  * or fitness for a particular purpose.  See the GNU Lesser General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  */
21 
22 #ifndef __NFS41_DAEMON_UTIL_H__
23 #define __NFS41_DAEMON_UTIL_H__
24 
25 #include "nfs41_types.h"
26 #include "from_kernel.h"
27 
28 extern DWORD NFS41D_VERSION;
29 struct __nfs41_session;
30 struct __nfs41_write_verf;
31 enum stable_how4;
32 
33 int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
34 int safe_write(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
35 int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name);
36 
37 const char* strip_path(
38     IN const char *path,
39     OUT uint32_t *len_out OPTIONAL);
40 
41 uint32_t max_read_size(
42     IN const struct __nfs41_session *session,
43     IN const nfs41_fh *fh);
44 uint32_t max_write_size(
45     IN const struct __nfs41_session *session,
46     IN const nfs41_fh *fh);
47 
48 bool_t verify_write(
49     IN nfs41_write_verf *verf,
50     IN OUT enum stable_how4 *stable);
51 bool_t verify_commit(
52     IN nfs41_write_verf *verf);
53 
54 /* bitmap4 */
bitmap_isset(IN const bitmap4 * mask,IN uint32_t word,IN uint32_t flag)55 static __inline bool_t bitmap_isset(
56     IN const bitmap4 *mask,
57     IN uint32_t word,
58     IN uint32_t flag)
59 {
60     return mask->count > word && mask->arr[word] & flag;
61 }
bitmap_set(IN bitmap4 * mask,IN uint32_t word,IN uint32_t flag)62 static __inline void bitmap_set(
63     IN bitmap4 *mask,
64     IN uint32_t word,
65     IN uint32_t flag)
66 {
67     if (mask->count > word)
68         mask->arr[word] |= flag;
69     else {
70         mask->count = word + 1;
71         mask->arr[word] = flag;
72     }
73 }
bitmap_unset(IN bitmap4 * mask,IN uint32_t word,IN uint32_t flag)74 static __inline void bitmap_unset(
75     IN bitmap4 *mask,
76     IN uint32_t word,
77     IN uint32_t flag)
78 {
79     if (mask->count > word) {
80         mask->arr[word] &= ~flag;
81         while (mask->count && mask->arr[mask->count-1] == 0)
82             mask->count--;
83     }
84 }
bitmap_intersect(IN bitmap4 * dst,IN const bitmap4 * src)85 static __inline void bitmap_intersect(
86     IN bitmap4 *dst,
87     IN const bitmap4 *src)
88 {
89     uint32_t i, count = 0;
90     for (i = 0; i < 3; i++) {
91         dst->arr[i] &= src->arr[i];
92         if (dst->arr[i])
93             count = i+1;
94     }
95     dst->count = min(dst->count, count);
96 }
97 
98 ULONG nfs_file_info_to_attributes(
99     IN const nfs41_file_info *info);
100 void nfs_to_basic_info(
101     IN const nfs41_file_info *info,
102     OUT PFILE_BASIC_INFO basic_out);
103 void nfs_to_standard_info(
104     IN const nfs41_file_info *info,
105     OUT PFILE_STANDARD_INFO std_out);
106 void nfs_to_network_openinfo(
107     IN const nfs41_file_info *info,
108     OUT PFILE_NETWORK_OPEN_INFORMATION std_out);
109 
110 /* http://msdn.microsoft.com/en-us/library/ms724290%28VS.85%29.aspx:
111  * A file time is a 64-bit value that represents the number of
112  * 100-nanosecond intervals that have elapsed since 12:00 A.M.
113  * January 1, 1601 Coordinated Universal Time (UTC). */
114 #define FILETIME_EPOCH 116444736000000000LL
115 
file_time_to_nfs_time(IN const PLARGE_INTEGER file_time,OUT nfstime4 * nfs_time)116 static __inline void file_time_to_nfs_time(
117     IN const PLARGE_INTEGER file_time,
118     OUT nfstime4 *nfs_time)
119 {
120     LONGLONG diff = file_time->QuadPart - FILETIME_EPOCH;
121     nfs_time->seconds = diff / 10000000;
122     nfs_time->nseconds = (uint32_t)((diff % 10000000)*100);
123 }
124 
nfs_time_to_file_time(IN const nfstime4 * nfs_time,OUT PLARGE_INTEGER file_time)125 static __inline void nfs_time_to_file_time(
126     IN const nfstime4 *nfs_time,
127     OUT PLARGE_INTEGER file_time)
128 {
129     file_time->QuadPart = FILETIME_EPOCH +
130         nfs_time->seconds * 10000000 +
131         nfs_time->nseconds / 100;
132 }
133 
134 void get_file_time(
135     OUT PLARGE_INTEGER file_time);
136 void get_nfs_time(
137     OUT nfstime4 *nfs_time);
138 
nfstime_normalize(IN OUT nfstime4 * nfstime)139 static __inline void nfstime_normalize(
140     IN OUT nfstime4 *nfstime)
141 {
142     /* return time in normalized form (0 <= nsec < 1s) */
143     while ((int32_t)nfstime->nseconds < 0) {
144         nfstime->nseconds += 1000000000;
145         nfstime->seconds--;
146     }
147 }
nfstime_diff(IN const nfstime4 * lhs,IN const nfstime4 * rhs,OUT nfstime4 * result)148 static __inline void nfstime_diff(
149     IN const nfstime4 *lhs,
150     IN const nfstime4 *rhs,
151     OUT nfstime4 *result)
152 {
153     /* result = lhs - rhs */
154     result->seconds = lhs->seconds - rhs->seconds;
155     result->nseconds = lhs->nseconds - rhs->nseconds;
156     nfstime_normalize(result);
157 }
nfstime_abs(IN const nfstime4 * nt,OUT nfstime4 * result)158 static __inline void nfstime_abs(
159     IN const nfstime4 *nt,
160     OUT nfstime4 *result)
161 {
162     if (nt->seconds < 0) {
163         const nfstime4 zero = { 0, 0 };
164         nfstime_diff(&zero, nt, result); /* result = 0 - nt */
165     } else if (result != nt)
166         memcpy(result, nt, sizeof(nfstime4));
167 }
168 
169 
170 int create_silly_rename(
171     IN nfs41_abs_path *path,
172     IN const nfs41_fh *fh,
173     OUT nfs41_component *silly);
174 
175 bool_t multi_addr_find(
176     IN const multi_addr4 *addrs,
177     IN const netaddr4 *addr,
178     OUT OPTIONAL uint32_t *index_out);
179 
180 /* nfs_to_windows_error
181  *   Returns a windows ERROR_ code corresponding to the given NFS4ERR_ status.
182  * If the status is outside the range of valid NFS4ERR_ values, it is returned
183  * unchanged.  Otherwise, if the status does not match a value in the mapping,
184  * a debug warning is generated and the default_error value is returned.
185  */
186 int nfs_to_windows_error(int status, int default_error);
187 
188 int map_symlink_errors(int status);
189 
190 #ifndef __REACTOS__
align8(uint32_t offset)191 __inline uint32_t align8(uint32_t offset) {
192 #else
193 FORCEINLINE uint32_t align8(uint32_t offset) {
194 #endif
195     return 8 + ((offset - 1) & ~7);
196 }
197 #ifndef __REACTOS__
198 __inline uint32_t align4(uint32_t offset) {
199 #else
200 FORCEINLINE uint32_t align4(uint32_t offset) {
201 #endif
202     return 4 + ((offset - 1) & ~3);
203 }
204 
205 /* path parsing */
206 #ifndef __REACTOS__
207 __inline int is_delimiter(char c) {
208 #else
209 FORCEINLINE int is_delimiter(char c) {
210 #endif
211     return c == '\\' || c == '/' || c == '\0';
212 }
213 #ifndef __REACTOS__
214 __inline const char* next_delimiter(const char *pos, const char *end) {
215 #else
216 FORCEINLINE const char* next_delimiter(const char *pos, const char *end) {
217 #endif
218     while (pos < end && !is_delimiter(*pos))
219         pos++;
220     return pos;
221 }
222 #ifndef __REACTOS__
223 __inline const char* prev_delimiter(const char *pos, const char *start) {
224 #else
225 FORCEINLINE const char* prev_delimiter(const char *pos, const char *start) {
226 #endif
227     while (pos > start && !is_delimiter(*pos))
228         pos--;
229     return pos;
230 }
231 #ifndef __REACTOS__
232 __inline const char* next_non_delimiter(const char *pos, const char *end) {
233 #else
234 FORCEINLINE const char* next_non_delimiter(const char *pos, const char *end) {
235 #endif
236     while (pos < end && is_delimiter(*pos))
237         pos++;
238     return pos;
239 }
240 #ifndef __REACTOS__
241 __inline const char* prev_non_delimiter(const char *pos, const char *start) {
242 #else
243 FORCEINLINE const char* prev_non_delimiter(const char *pos, const char *start) {
244 #endif
245     while (pos > start && is_delimiter(*pos))
246         pos--;
247     return pos;
248 }
249 
250 bool_t next_component(
251     IN const char *path,
252     IN const char *path_end,
253     OUT nfs41_component *component);
254 
255 bool_t last_component(
256     IN const char *path,
257     IN const char *path_end,
258     OUT nfs41_component *component);
259 
260 bool_t is_last_component(
261     IN const char *path,
262     IN const char *path_end);
263 
264 void abs_path_copy(
265     OUT nfs41_abs_path *dst,
266     IN const nfs41_abs_path *src);
267 
268 void path_fh_init(
269     OUT nfs41_path_fh *file,
270     IN nfs41_abs_path *path);
271 
272 void fh_copy(
273     OUT nfs41_fh *dst,
274     IN const nfs41_fh *src);
275 
276 void path_fh_copy(
277     OUT nfs41_path_fh *dst,
278     IN const nfs41_path_fh *src);
279 
280 #ifndef __REACTOS__
281 __inline int valid_handle(HANDLE handle) {
282 #else
283 FORCEINLINE int valid_handle(HANDLE handle) {
284 #endif
285     return handle != INVALID_HANDLE_VALUE && handle != 0;
286 }
287 
288 #endif /* !__NFS41_DAEMON_UTIL_H__ */
289