dfs_win32.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /*
  2. * File : rtthread.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE.
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2012-11-27 prife the first version
  13. */
  14. #include <rtthread.h>
  15. #include <dfs_fs.h>
  16. #include <dfs_def.h>
  17. #include <rtdevice.h>
  18. //#include "dfs_win32.h"
  19. #include <io.h>
  20. #include <fcntl.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <WinError.h>
  25. #include <windows.h>
  26. /*
  27. * RT-Thread DFS Interface for win-directory as an disk device
  28. */
  29. #define FILE_PATH_MAX 256 /* the longest file path */
  30. #define WIN32_DIRDISK_ROOT "." //"F:\\Project\\svn\\rtt\\trunk\\bsp\\simulator_test"
  31. static int win32_result_to_dfs(int res)
  32. {
  33. rt_kprintf("win error: %x", res);
  34. return -1;
  35. }
  36. static int dfs_win32_mount(
  37. struct dfs_filesystem *fs,
  38. unsigned long rwflag,
  39. const void *data)
  40. {
  41. return 0;
  42. }
  43. static int dfs_win32_unmount(struct dfs_filesystem *fs)
  44. {
  45. return 0;
  46. }
  47. static int dfs_win32_mkfs(const char *device_name)
  48. {
  49. return -DFS_STATUS_ENOSYS;
  50. }
  51. static int dfs_win32_statfs(struct dfs_filesystem *fs,
  52. struct statfs *buf)
  53. {
  54. return -DFS_STATUS_ENOSYS;
  55. }
  56. static char *winpath_dirdup(char *des, const char *src)
  57. {
  58. char *path;
  59. int i = 0;
  60. path = rt_malloc(FILE_PATH_MAX);
  61. if (path == RT_NULL)
  62. return RT_NULL;
  63. strcpy(path, des);
  64. strcat(path, src);
  65. while (1)
  66. {
  67. if (path[i] == 0)
  68. break;
  69. if (path[i] == '/')
  70. path[i] = '\\';
  71. i++;
  72. }
  73. return path;
  74. }
  75. static int dfs_win32_open(struct dfs_fd *file)
  76. {
  77. int fd;
  78. int oflag, mode;
  79. char *file_path;
  80. int res;
  81. oflag = file->flags;
  82. if (oflag & DFS_O_DIRECTORY) /* operations about dir */
  83. {
  84. struct _finddata_t dir;
  85. int handle;
  86. int len;
  87. file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
  88. if (oflag & DFS_O_CREAT) /* create a dir*/
  89. {
  90. res = CreateDirectory(file_path, NULL);
  91. if (res == ERROR_ALREADY_EXISTS)
  92. {
  93. rt_kprintf("already exists!\n");
  94. return -DFS_STATUS_EEXIST;
  95. }
  96. else if (res == ERROR_PATH_NOT_FOUND)
  97. {
  98. rt_kprintf("One or more intermediate directories do not exist!\n");
  99. return -DFS_STATUS_ENOENT;
  100. }
  101. }
  102. len = strlen(file_path);
  103. if (file_path[len - 1] != '\\')
  104. {
  105. file_path[len] = '\\';
  106. file_path[len + 1] = 0;
  107. }
  108. strcat(file_path, "*.*");
  109. /* _findfirst will get '.' */
  110. if ((handle = _findfirst(file_path, &dir)) == -1)
  111. {
  112. rt_free(file_path);
  113. goto __err;
  114. }
  115. /* save this pointer,will used by dfs_win32_getdents*/
  116. file->data = handle;
  117. rt_free(file_path);
  118. return DFS_STATUS_OK;
  119. }
  120. /* regular file operations */
  121. mode = O_BINARY;
  122. if (oflag & DFS_O_RDONLY) mode |= O_RDONLY;
  123. if (oflag & DFS_O_WRONLY) mode |= O_WRONLY;
  124. if (oflag & DFS_O_RDWR) mode |= O_RDWR;
  125. /* Opens the file, if it is existing. If not, a new file is created. */
  126. if (oflag & DFS_O_CREAT) mode |= O_CREAT;
  127. /* Creates a new file. If the file is existing, it is truncated and overwritten. */
  128. if (oflag & DFS_O_TRUNC) mode |= O_TRUNC;
  129. /* Creates a new file. The function fails if the file is already existing. */
  130. if (oflag & DFS_O_EXCL) mode |= O_EXCL;
  131. file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
  132. fd = _open(file_path, mode);
  133. rt_free(file_path);
  134. if (fd < 0)
  135. goto __err;
  136. /* save this pointer, it will be used when calling read(), write(),
  137. * flush(), seek(), and will be free when calling close()*/
  138. file->data = (void *)fd;
  139. file->pos = 0;
  140. file->size = _lseek(fd, 0, SEEK_END);
  141. if (oflag & DFS_O_APPEND)
  142. {
  143. file->pos = file->size;
  144. }
  145. else
  146. _lseek(fd, 0, SEEK_SET);
  147. return 0;
  148. __err:
  149. return win32_result_to_dfs(GetLastError());
  150. }
  151. static int dfs_win32_close(struct dfs_fd *file)
  152. {
  153. int oflag;
  154. oflag = file->flags;
  155. if (oflag & DFS_O_DIRECTORY)
  156. {
  157. /* operations about dir */
  158. if (_findclose((intptr_t)file->data) < 0)
  159. goto __err;
  160. return 0;
  161. }
  162. /* regular file operations */
  163. if (_close((int)(file->data)) < 0)
  164. goto __err;
  165. return 0;
  166. __err:
  167. return win32_result_to_dfs(GetLastError());
  168. }
  169. static int dfs_win32_ioctl(struct dfs_fd *file, int cmd, void *args)
  170. {
  171. return -DFS_STATUS_ENOSYS;
  172. }
  173. static int dfs_win32_read(struct dfs_fd *file, void *buf, rt_size_t len)
  174. {
  175. int fd;
  176. int char_read;
  177. fd = (int)(file->data);
  178. char_read = _read(fd, buf, len);
  179. if (char_read < 0)
  180. return win32_result_to_dfs(GetLastError());
  181. /* update position */
  182. file->pos = _lseek(fd, 0, SEEK_CUR);
  183. return char_read;
  184. }
  185. static int dfs_win32_write(struct dfs_fd *file,
  186. const void *buf,
  187. rt_size_t len)
  188. {
  189. int fd;
  190. int char_write;
  191. fd = (int)(file->data);
  192. char_write = _write(fd, buf, len);
  193. if (char_write < 0)
  194. return win32_result_to_dfs(GetLastError());
  195. /* update position */
  196. file->pos = _lseek(fd, 0, SEEK_CUR);
  197. return char_write;
  198. }
  199. static int dfs_win32_flush(struct dfs_fd *file)
  200. {
  201. return 0;
  202. }
  203. static int dfs_win32_seek(struct dfs_fd *file,
  204. rt_off_t offset)
  205. {
  206. int result;
  207. /* set offset as current offset */
  208. if (file->type == FT_DIRECTORY)
  209. {
  210. return -DFS_STATUS_ENOSYS;
  211. }
  212. else if (file->type == FT_REGULAR)
  213. {
  214. result = _lseek((int)(file->data), offset, SEEK_SET);
  215. if (result >= 0)
  216. return offset;
  217. }
  218. return win32_result_to_dfs(GetLastError());
  219. }
  220. /* return the size of struct dirent*/
  221. static int dfs_win32_getdents(
  222. struct dfs_fd *file,
  223. struct dirent *dirp,
  224. rt_uint32_t count)
  225. {
  226. rt_uint32_t index;
  227. struct dirent *d;
  228. struct _finddata_t fileinfo;
  229. int handle;
  230. int result;
  231. handle = (int)(file->data);
  232. RT_ASSERT(handle != RT_NULL);
  233. /* round count, count is always 1 */
  234. count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
  235. if (count == 0) return -DFS_STATUS_EINVAL;
  236. index = 0;
  237. /* usually, the while loop should only be looped only once! */
  238. while (1)
  239. {
  240. d = dirp + index;
  241. if (_findnext(handle, &fileinfo) != 0) //-1 failed
  242. goto __err;
  243. if (fileinfo.attrib & _A_SUBDIR)
  244. d->d_type = DFS_DT_DIR; /* directory */
  245. else
  246. d->d_type = DFS_DT_REG;
  247. /* write the rest arguments of struct dirent* dirp */
  248. d->d_namlen = strlen(fileinfo.name);
  249. d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
  250. strcpy(d->d_name, fileinfo.name);
  251. index ++;
  252. if (index * sizeof(struct dirent) >= count)
  253. break;
  254. }
  255. if (index == 0)
  256. return 0;
  257. file->pos += index * sizeof(struct dirent);
  258. return index * sizeof(struct dirent);
  259. __err:
  260. if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
  261. return 0;
  262. else
  263. return win32_result_to_dfs(result);
  264. }
  265. static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)
  266. {
  267. int result;
  268. char *fp;
  269. fp = winpath_dirdup(WIN32_DIRDISK_ROOT, path);
  270. if (fp == RT_NULL)
  271. {
  272. rt_kprintf("out of memory.\n");
  273. return -DFS_STATUS_ENOMEM;
  274. }
  275. result = GetFileAttributes(fp);
  276. if (result == INVALID_FILE_ATTRIBUTES)
  277. goto __err;
  278. if (result & FILE_ATTRIBUTE_DIRECTORY)//winnt.h
  279. {
  280. if (RemoveDirectory(fp) == RT_FALSE)
  281. goto __err;
  282. }
  283. else //(result & FILE_ATTRIBUTE_NORMAL)
  284. {
  285. if (_unlink(fp) < 0)
  286. goto __err;
  287. }
  288. rt_free(fp);
  289. return 0;
  290. __err:
  291. rt_free(fp);
  292. return win32_result_to_dfs(GetLastError());
  293. }
  294. static int dfs_win32_rename(
  295. struct dfs_filesystem *fs,
  296. const char *oldpath,
  297. const char *newpath)
  298. {
  299. int result;
  300. char *op, *np;
  301. op = winpath_dirdup(WIN32_DIRDISK_ROOT, oldpath);
  302. np = winpath_dirdup(WIN32_DIRDISK_ROOT, newpath);
  303. if (op == RT_NULL || np == RT_NULL)
  304. {
  305. rt_kprintf("out of memory.\n");
  306. return -DFS_STATUS_ENOMEM;
  307. }
  308. /* If the function fails, the return value is zero. */
  309. result = MoveFile(op, np);
  310. rt_free(op);
  311. rt_free(np);
  312. if (result == 0)
  313. return win32_result_to_dfs(GetLastError());
  314. return 0;
  315. }
  316. static int dfs_win32_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
  317. {
  318. WIN32_FIND_DATA fileInfo;
  319. HANDLE hFind;
  320. char *fp;
  321. fp = winpath_dirdup(WIN32_DIRDISK_ROOT, path);
  322. if (fp == RT_NULL)
  323. {
  324. rt_kprintf("out of memory.\n");
  325. return -DFS_STATUS_ENOMEM;
  326. }
  327. hFind = FindFirstFile(fp, &fileInfo);
  328. rt_free(fp);
  329. if (hFind == INVALID_HANDLE_VALUE)
  330. goto __err;
  331. st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
  332. DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
  333. /* convert file info to dfs stat structure */
  334. if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  335. {
  336. st->st_mode &= ~DFS_S_IFREG;
  337. st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
  338. }
  339. st->st_dev = 0;
  340. st->st_size = fileInfo.nFileSizeLow;
  341. st->st_mtime = 0;
  342. st->st_blksize = 0;
  343. FindClose(hFind);
  344. return 0;
  345. __err:
  346. return win32_result_to_dfs(GetLastError());
  347. }
  348. static const struct dfs_filesystem_operation dfs_win32_ops =
  349. {
  350. "wdir", /* file system type: dir */
  351. DFS_FS_FLAG_DEFAULT,
  352. dfs_win32_mount,
  353. dfs_win32_unmount,
  354. dfs_win32_mkfs,
  355. dfs_win32_statfs,
  356. dfs_win32_open,
  357. dfs_win32_close,
  358. dfs_win32_ioctl,
  359. dfs_win32_read,
  360. dfs_win32_write,
  361. dfs_win32_flush,
  362. dfs_win32_seek,
  363. dfs_win32_getdents,
  364. dfs_win32_unlink,
  365. dfs_win32_stat,
  366. dfs_win32_rename,
  367. };
  368. int dfs_win32_init(void)
  369. {
  370. /* register uffs file system */
  371. dfs_register(&dfs_win32_ops);
  372. return 0;
  373. }
  374. static rt_err_t nop_init(rt_device_t dev)
  375. {
  376. return RT_EOK;
  377. }
  378. static rt_err_t nop_open(rt_device_t dev, rt_uint16_t oflag)
  379. {
  380. return RT_EOK;
  381. }
  382. static rt_err_t nop_close(rt_device_t dev)
  383. {
  384. return RT_EOK;
  385. }
  386. static rt_size_t nop_read(rt_device_t dev,
  387. rt_off_t pos,
  388. void *buffer,
  389. rt_size_t size)
  390. {
  391. return size;
  392. }
  393. static rt_size_t nop_write(rt_device_t dev,
  394. rt_off_t pos,
  395. const void *buffer,
  396. rt_size_t size)
  397. {
  398. return size;
  399. }
  400. static rt_err_t nop_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  401. {
  402. return RT_EOK;
  403. }
  404. static struct rt_device win_sharedir_dev;
  405. rt_err_t rt_win_sharedir_init(const char *name)
  406. {
  407. rt_device_t dev;
  408. dev = &win_sharedir_dev;
  409. RT_ASSERT(dev != RT_NULL);
  410. /* set device class and generic device interface */
  411. dev->type = RT_Device_Class_Block;
  412. dev->init = nop_init;
  413. dev->open = nop_open;
  414. dev->read = nop_read;
  415. dev->write = nop_write;
  416. dev->close = nop_close;
  417. dev->control = nop_control;
  418. dev->rx_indicate = RT_NULL;
  419. dev->tx_complete = RT_NULL;
  420. /* register to RT-Thread device system */
  421. return rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
  422. }