1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2
3 #include "inc.h"
4
5 /*===========================================================================*
6 * hgfs_opendir *
7 *===========================================================================*/
hgfs_opendir(const char * path,sffs_dir_t * handle)8 int hgfs_opendir(const char *path, sffs_dir_t *handle)
9 {
10 /* Open a directory. Store a directory handle upon success.
11 */
12 int r;
13
14 RPC_REQUEST(HGFS_REQ_OPENDIR);
15
16 path_put(path);
17
18 if ((r = rpc_query()) != OK)
19 return r;
20
21 *handle = (sffs_dir_t)RPC_NEXT32;
22
23 return OK;
24 }
25
26 /*===========================================================================*
27 * hgfs_readdir *
28 *===========================================================================*/
hgfs_readdir(sffs_dir_t handle,unsigned int index,char * buf,size_t size,struct sffs_attr * attr)29 int hgfs_readdir(sffs_dir_t handle, unsigned int index, char *buf,
30 size_t size, struct sffs_attr *attr)
31 {
32 /* Read a directory entry from an open directory, using a zero-based index
33 * number. Upon success, the resulting path name is stored in the given buffer
34 * and the given attribute structure is filled selectively as requested. Upon
35 * error, the contents of the path buffer and attribute structure are
36 * undefined. ENOENT is returned upon end of directory.
37 */
38 int r;
39
40 RPC_REQUEST(HGFS_REQ_READDIR);
41 RPC_NEXT32 = (u32_t)handle;
42 RPC_NEXT32 = index;
43
44 /* EINVAL signifies end of directory. */
45 if ((r = rpc_query()) != OK)
46 return (r == EINVAL) ? ENOENT : OK;
47
48 attr_get(attr);
49
50 if ((r = path_get(buf, size)) != OK)
51 return r;
52
53 /* VMware Player 3 returns an empty name, instead of EINVAL, when reading
54 * from an EOF position right after opening the directory handle. Seems to be
55 * a newly introduced bug..
56 */
57 return (!buf[0]) ? ENOENT : OK;
58 }
59
60 /*===========================================================================*
61 * hgfs_closedir *
62 *===========================================================================*/
hgfs_closedir(sffs_dir_t handle)63 int hgfs_closedir(sffs_dir_t handle)
64 {
65 /* Close an open directory.
66 */
67
68 RPC_REQUEST(HGFS_REQ_CLOSEDIR);
69 RPC_NEXT32 = (u32_t)handle;
70
71 return rpc_query();
72 }
73