84 |
|
|
85 |
#if defined(SOLARIS) |
#if defined(SOLARIS) |
86 |
#include <sys/statvfs.h> /* solaris statvfs */ |
#include <sys/statvfs.h> /* solaris statvfs */ |
87 |
#define HAVE_STATVFS |
#define STATFS_FN(path, buf) (statvfs(path,buf)) |
88 |
|
#define STATFS_T statvfs |
89 |
#define F_NAMELEN(buf) ((buf).f_namemax) |
#define F_NAMELEN(buf) ((buf).f_namemax) |
90 |
|
|
91 |
#elif defined(__OpenBSD__) |
#elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)) |
92 |
#include <sys/param.h> |
#include <sys/param.h> |
93 |
#include <sys/mount.h> |
#include <sys/mount.h> |
94 |
#define HAVE_STATFS |
#define STATFS_FN(path, buf) (statfs(path,buf)) |
95 |
|
#define STATFS_T statfs |
96 |
#define F_NAMELEN(buf) (NAME_MAX) |
#define F_NAMELEN(buf) (NAME_MAX) |
97 |
|
|
98 |
#else |
#else |
99 |
#include <sys/vfs.h> /* linux statfs */ |
#include <sys/vfs.h> /* linux statfs */ |
100 |
#define HAVE_STATFS |
#define STATFS_FN(path, buf) (statfs(path,buf)) |
101 |
|
#define STATFS_T statfs |
102 |
#define F_NAMELEN(buf) ((buf).f_namelen) |
#define F_NAMELEN(buf) ((buf).f_namelen) |
103 |
#endif |
#endif |
104 |
|
|
117 |
} |
} |
118 |
g_fileinfo[MAX_OPEN_FILES]; |
g_fileinfo[MAX_OPEN_FILES]; |
119 |
|
|
|
struct fsinfo |
|
|
{ |
|
|
uint32 f_blocks, f_bfree, f_bsize, f_namelen; |
|
|
}; |
|
|
|
|
120 |
/* Convert seconds since 1970 to a filetime */ |
/* Convert seconds since 1970 to a filetime */ |
121 |
void |
void |
122 |
seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low) |
seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low) |
163 |
return count; |
return count; |
164 |
} |
} |
165 |
|
|
166 |
/* Opens of creates a file or directory */ |
/* Opens or creates a file or directory */ |
167 |
NTSTATUS |
NTSTATUS |
168 |
disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, |
disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, |
169 |
uint32 flags_and_attributes, char *filename, HANDLE * phandle) |
uint32 flags_and_attributes, char *filename, HANDLE * phandle) |
181 |
if (filename[strlen(filename) - 1] == '/') |
if (filename[strlen(filename) - 1] == '/') |
182 |
filename[strlen(filename) - 1] = 0; |
filename[strlen(filename) - 1] = 0; |
183 |
sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename); |
sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename); |
|
//printf("Open: %s\n", path); |
|
184 |
|
|
185 |
switch (create_disposition) |
switch (create_disposition) |
186 |
{ |
{ |
215 |
break; |
break; |
216 |
} |
} |
217 |
|
|
218 |
if (flags_and_attributes & FILE_DIRECTORY_FILE) |
/* the sad part is that we can't trust this flag */ |
219 |
|
/* directories aren't always marked */ |
220 |
|
if (flags_and_attributes ^ FILE_DIRECTORY_FILE) |
221 |
{ |
{ |
222 |
if (flags & O_CREAT) |
if (accessmask & GENERIC_ALL |
223 |
|
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) |
224 |
{ |
{ |
225 |
mkdir(path, mode); |
flags |= O_RDWR; |
226 |
|
} |
227 |
|
else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) |
228 |
|
{ |
229 |
|
flags |= O_WRONLY; |
230 |
|
} |
231 |
|
else |
232 |
|
{ |
233 |
|
flags |= O_RDONLY; |
234 |
} |
} |
235 |
|
|
236 |
dirp = opendir(path); |
handle = open(path, flags, mode); |
237 |
if (!dirp) |
if (handle == -1) |
238 |
{ |
{ |
239 |
switch (errno) |
switch (errno) |
240 |
{ |
{ |
248 |
|
|
249 |
default: |
default: |
250 |
|
|
251 |
perror("opendir"); |
perror("open"); |
252 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
253 |
} |
} |
254 |
} |
} |
255 |
handle = DIRFD(dirp); |
|
256 |
|
/* all read and writes of files should be non blocking */ |
257 |
|
if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1) |
258 |
|
perror("fcntl"); |
259 |
} |
} |
260 |
else |
|
261 |
|
/* since we can't trust the FILE_DIRECTORY_FILE flag */ |
262 |
|
/* we need to double check that the file isn't a dir */ |
263 |
|
if (handle != 0) |
264 |
{ |
{ |
265 |
if (accessmask & GENERIC_ALL |
/* Must check if this file isn't actually a directory */ |
266 |
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) |
struct stat filestat; |
267 |
{ |
|
268 |
flags |= O_RDWR; |
// Get information about file and set that flag ourselfs |
269 |
} |
if ((fstat(handle, &filestat) == 0) && (S_ISDIR(filestat.st_mode))) |
|
else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) |
|
270 |
{ |
{ |
271 |
flags |= O_WRONLY; |
flags_and_attributes |= FILE_DIRECTORY_FILE; |
272 |
|
close(handle); |
273 |
|
handle = 0; |
274 |
} |
} |
275 |
else |
} |
276 |
|
|
277 |
|
|
278 |
|
if (flags_and_attributes & FILE_DIRECTORY_FILE) |
279 |
|
{ |
280 |
|
if (flags & O_CREAT) |
281 |
{ |
{ |
282 |
flags |= O_RDONLY; |
mkdir(path, mode); |
283 |
} |
} |
284 |
|
|
285 |
handle = open(path, flags, mode); |
dirp = opendir(path); |
286 |
if (handle == -1) |
if (!dirp) |
287 |
{ |
{ |
288 |
switch (errno) |
switch (errno) |
289 |
{ |
{ |
297 |
|
|
298 |
default: |
default: |
299 |
|
|
300 |
perror("open"); |
perror("opendir"); |
301 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
302 |
} |
} |
303 |
} |
} |
304 |
|
handle = DIRFD(dirp); |
305 |
} |
} |
306 |
|
|
307 |
if (handle >= MAX_OPEN_FILES) |
if (handle >= MAX_OPEN_FILES) |
315 |
g_fileinfo[handle].pdir = dirp; |
g_fileinfo[handle].pdir = dirp; |
316 |
g_fileinfo[handle].device_id = device_id; |
g_fileinfo[handle].device_id = device_id; |
317 |
g_fileinfo[handle].flags_and_attributes = flags_and_attributes; |
g_fileinfo[handle].flags_and_attributes = flags_and_attributes; |
318 |
|
// printf("create: attrib: %u handle %u\n", g_fileinfo[handle].flags_and_attributes, handle ); |
319 |
strncpy(g_fileinfo[handle].path, path, 255); |
strncpy(g_fileinfo[handle].path, path, 255); |
320 |
|
|
321 |
*phandle = handle; |
*phandle = handle; |
347 |
{ |
{ |
348 |
int n; |
int n; |
349 |
|
|
350 |
|
/* browsing dir ???? */ |
351 |
|
/* each request is 24 bytes */ |
352 |
|
if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE) |
353 |
|
{ |
354 |
|
*result = 0; |
355 |
|
return STATUS_SUCCESS; |
356 |
|
} |
357 |
|
|
358 |
if (offset) |
if (offset) |
359 |
lseek(handle, offset, SEEK_SET); |
lseek(handle, offset, SEEK_SET); |
360 |
n = read(handle, data, length); |
n = read(handle, data, length); |
534 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
535 |
} |
} |
536 |
|
|
|
int fsstat(const char *path, struct fsinfo *buf) |
|
|
{ |
|
|
int ret; |
|
|
#if defined(HAVE_STATFS) |
|
|
struct statfs statbuf; |
|
|
#elif defined(HAVE_STATVFS) |
|
|
struct statvfs statbuf; |
|
|
#endif |
|
|
|
|
|
#if defined(HAVE_STATFS) |
|
|
ret = statfs(path, &statbuf); |
|
|
#elif defined(HAVE_STATVFS) |
|
|
ret = statvfs(path, &statbuf); |
|
|
#else |
|
|
ret=-1; |
|
|
#endif |
|
|
|
|
|
buf->f_blocks = statbuf.f_blocks; |
|
|
buf->f_bfree = statbuf.f_bfree; |
|
|
buf->f_bsize = statbuf.f_bsize; |
|
|
buf->f_namelen = F_NAMELEN(statbuf); |
|
|
|
|
|
return ret; |
|
|
} |
|
|
|
|
537 |
NTSTATUS |
NTSTATUS |
538 |
disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out) |
disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out) |
539 |
{ |
{ |
540 |
char *volume, *fs_type; |
char *volume, *fs_type; |
541 |
struct fsinfo stat_fs; |
struct STATFS_T stat_fs; |
542 |
struct fileinfo *pfinfo; |
struct fileinfo *pfinfo; |
543 |
|
|
544 |
pfinfo = &(g_fileinfo[handle]); |
pfinfo = &(g_fileinfo[handle]); |
545 |
volume = "RDESKTOP"; |
volume = "RDESKTOP"; |
546 |
fs_type = "RDPFS"; |
fs_type = "RDPFS"; |
547 |
|
|
548 |
if (fsstat(pfinfo->path, &stat_fs) != 0) /* FIXME: statfs is not portable */ |
if (STATFS_FN(pfinfo->path, &stat_fs) != 0) /* FIXME: statfs is not portable */ |
549 |
{ |
{ |
550 |
perror("statfs"); |
perror("statfs"); |
551 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
576 |
case 5: /* FileFsAttributeInformation */ |
case 5: /* FileFsAttributeInformation */ |
577 |
|
|
578 |
out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED); /* fs attributes */ |
out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED); /* fs attributes */ |
579 |
out_uint32_le(out, stat_fs.f_namelen); /* max length of filename */ |
out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */ |
580 |
out_uint32_le(out, 2 * strlen(fs_type)); /* length of fs_type */ |
out_uint32_le(out, 2 * strlen(fs_type)); /* length of fs_type */ |
581 |
rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2); |
rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2); |
582 |
break; |
break; |
635 |
|
|
636 |
// Get information for directory entry |
// Get information for directory entry |
637 |
sprintf(fullpath, "%s/%s", dirname, pdirent->d_name); |
sprintf(fullpath, "%s/%s", dirname, pdirent->d_name); |
638 |
/* JIF |
/* JIF |
639 |
printf("Stat: %s\n", fullpath); */ |
printf("Stat: %s\n", fullpath); */ |
640 |
if (stat(fullpath, &fstat)) |
if (stat(fullpath, &fstat)) |
641 |
{ |
{ |