filesys.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. #ifdef _DEBUG
  2. #include "../mmage/mmage.h" // for ShowError()
  3. #endif
  4. #include "../mmage/preference.h"
  5. #include "filesys.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <tchar.h>
  9. #ifdef __GNUC__
  10. #if defined(_MBCS)
  11. #define _tmakepath _makepath
  12. #define _tsplitpath _splitpath
  13. #elif defined(_UNICODE)
  14. #define _tmakepath _wmakepath
  15. #define _tsplitpath _wplitpath
  16. #else
  17. #define _tmakepath _makepath
  18. #define _tsplitpath _splitpath
  19. #endif
  20. #endif
  21. extern LPMMVM mmvm;
  22. typedef struct {
  23. LPTSTR rom0names[ROM0FS_NUM_ENTRIES];
  24. LPTSTR ram0names[RAM0FS_NUM_ENTRIES];
  25. HANDLE fd[OPEN_MAX];
  26. TCHAR rom0dirname[MAX_PATH];
  27. TCHAR ram0dirname[MAX_PATH];
  28. } FILETABLE, *LPFILETABLE;
  29. static TCHAR rom0names[ROM0FS_NUM_ENTRIES][MAX_PATH + 1];
  30. static TCHAR ram0names[RAM0FS_NUM_ENTRIES][MAX_PATH + 1];
  31. static FILETABLE ftable_struct;
  32. static LPFILETABLE ftable = &ftable_struct;
  33. static void InitFent(WW_FS fs);
  34. static WW_FARPTR wwfs_entries(WW_FS fs);
  35. static WW_INT wwfs_n_entries(WW_FS fs);
  36. static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep);
  37. static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep);
  38. static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname);
  39. static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms);
  40. static WW_INT wwfs_close(WW_INT fd);
  41. static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len);
  42. static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len);
  43. static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin);
  44. static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode);
  45. static WW_INT wwfs_freeze(WW_FS fs, char *fname);
  46. static WW_INT wwfs_melt(WW_FS fs, char *fname);
  47. static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep);
  48. static WW_INT wwfs_unlink(WW_FS fs, char *fname);
  49. static WW_INT wwfs_newfs(WW_FS fs);
  50. static WW_INT wwfs_defrag(WW_FS fs);
  51. static WW_LONG wwfs_space(WW_FS fs);
  52. // fs からファイル名 fname のエントリを取得(内部関数)
  53. static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n);
  54. void InitFilesys(LPMMVM mmvm) {
  55. HANDLE ffile;
  56. TCHAR ffind[MAX_PATH + 1];
  57. TCHAR w32path[MAX_PATH + 1];
  58. WIN32_FIND_DATA fdata;
  59. TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR];
  60. int i;
  61. // initialize file entries
  62. for(i = 0; i < ROOTFS_NUM_ENTRIES; i++) {
  63. InitFent(&(mmvm->swork->_root_fs_entries[i]));
  64. }
  65. for(i = 0; i < ROM0FS_NUM_ENTRIES; i++) {
  66. InitFent(&(mmvm->swork->_rom0_fs_entries[i]));
  67. ftable->rom0names[i] = &rom0names[i][0];
  68. }
  69. for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
  70. InitFent(&(mmvm->swork->_ram0_fs_entries[i]));
  71. ftable->ram0names[i] = &ram0names[i][0];
  72. }
  73. // setup root fs
  74. for(i = 0; i < DIRENT_NUM; i++) {
  75. mmvm->swork->_root_fs_entries[i].mode = FMODE_DIR|FMODE_R|FMODE_W|FMODE_X;
  76. mmvm->swork->_root_fs_entries[i].handler.il = GETFARPTR(mmvm->il->fs);
  77. }
  78. strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROOT].name, ".");
  79. mmvm->swork->_root_fs_entries[DIRENT_ROOT].count = DIRENT_NUM;
  80. strcpy(mmvm->swork->_root_fs_entries[DIRENT_KERN].name, "kern");
  81. mmvm->swork->_root_fs_entries[DIRENT_KERN].count = 0;
  82. strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROM0].name, "rom0");
  83. mmvm->swork->_root_fs_entries[DIRENT_ROM0].count = ROM0FS_NUM_ENTRIES;
  84. strcpy(mmvm->swork->_root_fs_entries[DIRENT_RAM0].name, "ram0");
  85. mmvm->swork->_root_fs_entries[DIRENT_RAM0].count = RAM0FS_NUM_ENTRIES;
  86. // initialize file handles
  87. for(i = 0; i < OPEN_MAX; i++) {
  88. if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
  89. CloseHandle(ftable->fd[i]);
  90. ftable->fd[i] = INVALID_HANDLE_VALUE;
  91. }
  92. mmvm->swork->_openfiles[i].omode = 0;
  93. }
  94. // initialize /rom0 file entries
  95. i = 0;
  96. if(_tcslen(mmconfig->rom0dir)) {
  97. _stprintf(ffind, TEXT("%s\\*"), mmconfig->rom0dir);
  98. _tcscpy(ftable->rom0dirname, mmconfig->rom0dir);
  99. } else {
  100. _stprintf(ffind, TEXT("%s\\rom0\\*"), mmconfig->workingdir);
  101. _stprintf(ftable->rom0dirname, TEXT("%s\\rom0\\"), mmconfig->workingdir);
  102. }
  103. _tsplitpath(ffind, drive, dir, NULL, NULL);
  104. ffile = FindFirstFile(ffind, &fdata);
  105. if(ffile != INVALID_HANDLE_VALUE) {
  106. do {
  107. if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  108. strncpy(mmvm->swork->_rom0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
  109. mmvm->swork->_rom0_fs_entries[i].count = 0;
  110. mmvm->swork->_rom0_fs_entries[i].mode = FMODE_R;
  111. mmvm->swork->_rom0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
  112. mmvm->swork->_rom0_fs_entries[i].len = fdata.nFileSizeLow;
  113. _tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
  114. _tcscpy(ftable->rom0names[i], w32path);
  115. i++;
  116. if(i > ROM0FS_NUM_ENTRIES)
  117. break;
  118. }
  119. } while(FindNextFile(ffile, &fdata));
  120. FindClose(ffile);
  121. }
  122. // initialize /ram0 file entries
  123. i = 0;
  124. if(_tcslen(mmconfig->ram0dir)) {
  125. _stprintf(ffind, TEXT("%s\\*"), mmconfig->ram0dir);
  126. _tcscpy(ftable->ram0dirname, mmconfig->ram0dir);
  127. } else {
  128. _stprintf(ffind, TEXT("%s\\ram0\\*"), mmconfig->workingdir);
  129. _stprintf(ftable->ram0dirname, TEXT("%s\\ram0\\"), mmconfig->workingdir);
  130. }
  131. _tsplitpath(ffind, drive, dir, NULL, NULL);
  132. ffile = FindFirstFile(ffind, &fdata);
  133. if(ffile != INVALID_HANDLE_VALUE) {
  134. do {
  135. if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  136. strncpy(mmvm->swork->_ram0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
  137. mmvm->swork->_ram0_fs_entries[i].count = 0;
  138. mmvm->swork->_ram0_fs_entries[i].mode = FMODE_R|FMODE_W;
  139. mmvm->swork->_ram0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
  140. mmvm->swork->_ram0_fs_entries[i].len = fdata.nFileSizeLow;
  141. _tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
  142. _tcscpy(ftable->ram0names[i], w32path);
  143. i++;
  144. if(i > RAM0FS_NUM_ENTRIES)
  145. break;
  146. }
  147. } while(FindNextFile(ffile, &fdata));
  148. FindClose(ffile);
  149. }
  150. }
  151. void CloseFilesys() {
  152. int i;
  153. for(i = 0; i < OPEN_MAX; i++) {
  154. if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
  155. CloseHandle(ftable->fd[i]);
  156. ftable->fd[i] = INVALID_HANDLE_VALUE;
  157. }
  158. mmvm->swork->_openfiles[i].omode = 0;
  159. }
  160. }
  161. void HandleFsIL(LPMMVM mmvm) {
  162. WW_FARPTR p, ret;
  163. WW_INT n, mode, perms, fd, len, origin;
  164. WW_FS fs, fep;
  165. char *fname, *buf;
  166. WW_LONG offset;
  167. switch(ip) {
  168. case 0: // ILInfo far *super._get_info();
  169. wregs[DX] = GETSEG(mmvm->il->fs);
  170. wregs[AX] = 0x0100;
  171. break;
  172. case 1: // fent_t far *(far *_entries)(FS fs);
  173. p = *((WW_FARPTR *)GetArgAddr(0));
  174. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  175. ret = wwfs_entries(fs);
  176. wregs[AX] = ret.segoff.off;
  177. wregs[DX] = ret.segoff.seg;
  178. break;
  179. case 2: // int (far *_n_entries)(FS fs);
  180. p = *((WW_FARPTR *)GetArgAddr(0));
  181. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  182. wregs[AX] = wwfs_n_entries(fs);
  183. break;
  184. case 3: // int (far *_getent)(FS fs, int n, fent_t far *fep);
  185. p = *((WW_FARPTR *)GetArgAddr(0));
  186. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  187. n = *((WW_INT *)GetArgAddr(4));
  188. p = *((WW_FARPTR *)GetArgAddr(6));
  189. fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
  190. wregs[AX] = wwfs_getent(fs, n, fep);
  191. break;
  192. case 4: // int (far *_findent)(FS fs, char far *fname, fent_t far *fep);
  193. p = *((WW_FARPTR *)GetArgAddr(0));
  194. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  195. p = *((WW_FARPTR *)GetArgAddr(4));
  196. fname = (char *)&memory[FARPTR2ADDR(p)];
  197. p = *((WW_FARPTR *)GetArgAddr(8));
  198. fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
  199. wregs[AX] = wwfs_findent(fs, fname, fep);
  200. break;
  201. case 5: // void far *(far *_mmap)(FS fs, char far *fname);
  202. p = *((WW_FARPTR *)GetArgAddr(0));
  203. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  204. p = *((WW_FARPTR *)GetArgAddr(4));
  205. fname = (char *)&memory[FARPTR2ADDR(p)];
  206. ret = wwfs_mmap(fs, fname);
  207. wregs[AX] = ret.segoff.off;
  208. wregs[DX] = ret.segoff.seg;
  209. break;
  210. case 6: // int (far *_open)(FS fs, char far *fname, int mode, int perms);
  211. p = *((WW_FARPTR *)GetArgAddr(0));
  212. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  213. p = *((WW_FARPTR *)GetArgAddr(4));
  214. fname = (char *)&memory[FARPTR2ADDR(p)];
  215. mode = *((WW_INT *)GetArgAddr(8));
  216. perms = *((WW_INT *)GetArgAddr(10));
  217. wregs[AX] = wwfs_open(fs, fname, mode, perms);
  218. break;
  219. case 7: // int (far *_close)(int fd);
  220. fd = *((WW_INT *)GetArgAddr(0));
  221. wregs[AX] = wwfs_close(fd);
  222. break;
  223. case 8: // int (far *_read)(int fd, char far *buf, int len);
  224. fd = *((WW_INT *)GetArgAddr(0));
  225. p = *((WW_FARPTR *)GetArgAddr(2));
  226. buf = (char *)&memory[FARPTR2ADDR(p)];
  227. len = *((WW_INT *)GetArgAddr(6));
  228. wregs[AX] = wwfs_read(fd, buf, len);
  229. break;
  230. case 9: // int (far *_write)(int fd, char far *buf, int len);
  231. fd = *((WW_INT *)GetArgAddr(0));
  232. p = *((WW_FARPTR *)GetArgAddr(2));
  233. buf = (char *)&memory[FARPTR2ADDR(p)];
  234. len = *((WW_INT *)GetArgAddr(6));
  235. wregs[AX] = wwfs_write(fd, buf, len);
  236. break;
  237. case 10: // long (far *_lseek)(int fd, long offset, int origin);
  238. fd = *((WW_INT *)GetArgAddr(0));
  239. offset = *((WW_LONG *)GetArgAddr(2));
  240. origin = *((WW_INT *)GetArgAddr(6));
  241. ret.farptr = wwfs_lseek(fd, offset, origin);
  242. wregs[AX] = ret.segoff.off;
  243. wregs[DX] = ret.segoff.seg;
  244. break;
  245. case 11: // int (far *_chmod)(FS fs, char far *fname, int mode);
  246. p = *((WW_FARPTR *)GetArgAddr(0));
  247. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  248. p = *((WW_FARPTR *)GetArgAddr(4));
  249. fname = (char *)&memory[FARPTR2ADDR(p)];
  250. mode = *((WW_INT *)GetArgAddr(8));
  251. wregs[AX] = wwfs_chmod(fs, fname, mode);
  252. break;
  253. case 12: // int (far *_freeze)(FS fs, char far *fname);
  254. p = *((WW_FARPTR *)GetArgAddr(0));
  255. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  256. p = *((WW_FARPTR *)GetArgAddr(4));
  257. fname = (char *)&memory[FARPTR2ADDR(p)];
  258. wregs[AX] = wwfs_freeze(fs, fname);
  259. break;
  260. case 13: // int (far *_melt)(FS fs, char far *fname);
  261. p = *((WW_FARPTR *)GetArgAddr(0));
  262. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  263. p = *((WW_FARPTR *)GetArgAddr(4));
  264. fname = (char *)&memory[FARPTR2ADDR(p)];
  265. wregs[AX] = wwfs_melt(fs, fname);
  266. break;
  267. case 14: // int (far *_creat)(FS fs, fent_t far *fep);
  268. p = *((WW_FARPTR *)GetArgAddr(0));
  269. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  270. p = *((WW_FARPTR *)GetArgAddr(4));
  271. fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
  272. wregs[AX] = wwfs_creat(fs, fep);
  273. break;
  274. case 15: // int (far *_unlink)(FS fs, char *fname);
  275. p = *((WW_FARPTR *)GetArgAddr(0));
  276. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  277. p = *((WW_FARPTR *)GetArgAddr(4));
  278. fname = (char *)&memory[FARPTR2ADDR(p)];
  279. wregs[AX] = wwfs_unlink(fs, fname);
  280. break;
  281. case 16: // int (far *_newfs)(FS fs);
  282. p = *((WW_FARPTR *)GetArgAddr(0));
  283. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  284. wregs[AX] = wwfs_newfs(fs);
  285. break;
  286. case 17: // int (far *_defrag)(FS fs);
  287. p = *((WW_FARPTR *)GetArgAddr(0));
  288. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  289. wregs[AX] = wwfs_defrag(fs);
  290. break;
  291. case 18: // unsigned long (far *_space)(FS fs);
  292. p = *((WW_FARPTR *)GetArgAddr(0));
  293. fs = (WW_FS)&memory[FARPTR2ADDR(p)];
  294. ret.farptr = wwfs_space(fs);
  295. wregs[AX] = ret.segoff.off;
  296. wregs[DX] = ret.segoff.seg;
  297. break;
  298. default:
  299. break;
  300. }
  301. ILReturn();
  302. }
  303. static WW_FARPTR wwfs_entries(WW_FS fs) {
  304. WW_FARPTR ret;
  305. if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
  306. ret.segoff.seg = SRAMWORK_SEG;
  307. ret.segoff.off = (LPBYTE)(mmvm->swork->_root_fs_entries) - (LPBYTE)(mmvm->swork);
  308. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
  309. ret.segoff.seg = SRAMWORK_SEG;
  310. ret.segoff.off = (LPBYTE)(mmvm->swork->_rom0_fs_entries) - (LPBYTE)(mmvm->swork);
  311. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
  312. ret.segoff.seg = SRAMWORK_SEG;
  313. ret.segoff.off = (LPBYTE)(mmvm->swork->_ram0_fs_entries) - (LPBYTE)(mmvm->swork);
  314. } else {
  315. ret.farptr = NULL;
  316. }
  317. return ret;
  318. }
  319. static WW_INT wwfs_n_entries(WW_FS fs) {
  320. WW_INT ret;
  321. if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
  322. ret = ROOTFS_NUM_ENTRIES;
  323. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
  324. ret = ROM0FS_NUM_ENTRIES;
  325. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
  326. ret = RAM0FS_NUM_ENTRIES;
  327. } else {
  328. ret = E_FS_FILE_NOT_FOUND;
  329. }
  330. return ret;
  331. }
  332. static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep) {
  333. WW_INT ret;
  334. if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
  335. if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
  336. memcpy(fep, &(mmvm->swork->_root_fs_entries[n]), sizeof(WW_FENT_T));
  337. ret = E_FS_SUCCESS;
  338. } else {
  339. ret = E_FS_OUT_OF_BOUNDS;
  340. }
  341. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
  342. if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
  343. memcpy(fep, &(mmvm->swork->_rom0_fs_entries[n]), sizeof(WW_FENT_T));
  344. ret = E_FS_SUCCESS;
  345. } else {
  346. ret = E_FS_OUT_OF_BOUNDS;
  347. }
  348. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
  349. if(n >= 0 && n < RAM0FS_NUM_ENTRIES) {
  350. memcpy(fep, &(mmvm->swork->_ram0_fs_entries[n]), sizeof(WW_FENT_T));
  351. ret = E_FS_SUCCESS;
  352. } else {
  353. ret = E_FS_OUT_OF_BOUNDS;
  354. }
  355. } else {
  356. ret = E_FS_FILE_NOT_FOUND;
  357. }
  358. return ret;
  359. }
  360. static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep) {
  361. WW_INT ret;
  362. WW_FENT_T *fents;
  363. WW_INT n;
  364. fents = findent(fs, fname, &n);
  365. if(fents) {
  366. memcpy(fep, &fents, sizeof(WW_FENT_T));
  367. ret = E_FS_SUCCESS;
  368. } else {
  369. ret = E_FS_FILE_NOT_FOUND;
  370. }
  371. return ret;
  372. }
  373. static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname) {
  374. WW_FARPTR ret;
  375. // not supported
  376. ret.farptr = 0;
  377. return ret;
  378. }
  379. static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms) {
  380. WW_INT ret;
  381. WW_FENT_T *fents;
  382. LPTSTR *fntable;
  383. DWORD w32mode;
  384. LPTSTR w32fname;
  385. WW_INT nfent;
  386. WW_FENT_T newfile;
  387. switch(mode) {
  388. case FMODE_R:
  389. w32mode = GENERIC_READ;
  390. break;
  391. case FMODE_W:
  392. w32mode = GENERIC_WRITE;
  393. break;
  394. case (FMODE_R|FMODE_W):
  395. w32mode = (GENERIC_READ|GENERIC_WRITE);
  396. break;
  397. default:
  398. return E_FS_PERMISSION_DENIED;
  399. break;
  400. }
  401. if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
  402. fntable = ftable->rom0names;
  403. if(mode & FMODE_W)
  404. return E_FS_PERMISSION_DENIED;
  405. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
  406. fntable = ftable->ram0names;
  407. } else {
  408. return E_FS_FILE_NOT_FOUND;
  409. }
  410. fents = findent(fs, fname, &nfent);
  411. if(!fents) {
  412. // ファイルが見つからなかったら新しいファイルを作る
  413. InitFent(&newfile);
  414. strncpy(newfile.name, fname, MAXPATHLEN);
  415. newfile.mode = mode;
  416. if(wwfs_creat(fs, &newfile) != E_FS_SUCCESS)
  417. return E_FS_FILE_NOT_FOUND;
  418. fents = findent(fs, fname, &nfent);
  419. if(!fents)
  420. return E_FS_FILE_NOT_FOUND;
  421. }
  422. w32fname = fntable[nfent];
  423. for(ret = 0; ret < OPEN_MAX; ret++) {
  424. if(ftable->fd[ret] == INVALID_HANDLE_VALUE)
  425. break;
  426. }
  427. if(ret == OPEN_MAX) {
  428. ret = E_FS_ERROR;
  429. } else {
  430. ftable->fd[ret] = CreateFile(w32fname, w32mode, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  431. if(ftable->fd[ret] == INVALID_HANDLE_VALUE) {
  432. ret = E_FS_PERMISSION_DENIED;
  433. } else {
  434. mmvm->swork->_openfiles[ret].fs = (WW_FS)mmvm->cwfs.farptr;
  435. mmvm->swork->_openfiles[ret].fentp.segoff.seg = SRAMWORK_SEG;
  436. mmvm->swork->_openfiles[ret].fentp.segoff.off = (LPBYTE)&fents - (LPBYTE)mmvm->swork;
  437. mmvm->swork->_openfiles[ret].omode = mode;
  438. mmvm->swork->_openfiles[ret].fpos = 0;
  439. mmvm->swork->_openfiles[ret].flen = 0;
  440. mmvm->swork->_openfiles[ret].floc.farptr = 0;
  441. mmvm->swork->_openfiles[ret].count = 0;
  442. mmvm->swork->_openfiles[ret].pcb = 1;
  443. mmvm->swork->_openfiles[ret].driver.farptr = 0;
  444. }
  445. }
  446. return ret;
  447. }
  448. static WW_INT wwfs_close(WW_INT fd) {
  449. WW_INT ret;
  450. if(!(mmvm->swork->_openfiles[fd].omode))
  451. return E_FS_ERROR;
  452. if(ftable->fd[fd] != INVALID_HANDLE_VALUE) {
  453. if(CloseHandle(ftable->fd[fd]))
  454. ret = E_FS_SUCCESS;
  455. else
  456. ret = E_FS_FILE_NOT_OPEN;
  457. } else {
  458. ret = E_FS_FILE_NOT_OPEN;
  459. }
  460. ftable->fd[fd] = INVALID_HANDLE_VALUE;
  461. mmvm->swork->_openfiles[fd].omode = 0;
  462. return ret;
  463. }
  464. static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len) {
  465. WW_INT ret;
  466. DWORD nbytes;
  467. if(!(mmvm->swork->_openfiles[fd].omode))
  468. return E_FS_ERROR;
  469. if(!(mmvm->swork->_openfiles[fd].omode & FMODE_R))
  470. return E_FS_PERMISSION_DENIED;
  471. if(ReadFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
  472. ret = (WW_INT)nbytes;
  473. } else {
  474. ret = -1;
  475. }
  476. return ret;
  477. }
  478. static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len) {
  479. WW_INT ret;
  480. DWORD nbytes;
  481. if(!(mmvm->swork->_openfiles[fd].omode))
  482. return E_FS_ERROR;
  483. if(!(mmvm->swork->_openfiles[fd].omode & FMODE_W))
  484. return E_FS_PERMISSION_DENIED;
  485. if(WriteFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
  486. ret = (WW_INT)nbytes;
  487. } else {
  488. ret = -1;
  489. }
  490. return ret;
  491. }
  492. static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin) {
  493. WW_LONG ret;
  494. DWORD w32off, w32org;
  495. if(!(mmvm->swork->_openfiles[fd].omode))
  496. return E_FS_ERROR;
  497. switch(origin) {
  498. case 0:
  499. w32org = FILE_BEGIN;
  500. break;
  501. case 1:
  502. w32org = FILE_CURRENT;
  503. break;
  504. case 2:
  505. w32org = FILE_END;
  506. break;
  507. default:
  508. return E_FS_OUT_OF_BOUNDS;
  509. break;
  510. }
  511. if(ftable->fd[fd] == INVALID_HANDLE_VALUE) {
  512. ret = E_FS_FILE_NOT_OPEN;
  513. } else {
  514. w32off = SetFilePointer(ftable->fd[fd], offset, NULL, w32org);
  515. if(w32off != 0xFFFFFFFF)
  516. ret = w32off;
  517. else
  518. ret = E_FS_OUT_OF_BOUNDS;
  519. }
  520. return ret;
  521. }
  522. // not yet.
  523. static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode) {
  524. return E_FS_ERROR;
  525. }
  526. static WW_INT wwfs_freeze(WW_FS fs, char *fname) {
  527. return E_FS_ERROR;
  528. }
  529. static WW_INT wwfs_melt(WW_FS fs, char *fname) {
  530. return E_FS_ERROR;
  531. }
  532. static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep) {
  533. WW_FENT_T *fent;
  534. WW_INT n;
  535. HANDLE newfile;
  536. int i;
  537. if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
  538. return E_FS_PERMISSION_DENIED;
  539. if(findent(fs, fep->name, &n))
  540. return E_FS_ERROR;
  541. fent = NULL;
  542. for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
  543. if(mmvm->swork->_ram0_fs_entries[i].count == (WW_INT)-1) {
  544. fent = &(mmvm->swork->_ram0_fs_entries[i]);
  545. n = i;
  546. break;
  547. }
  548. }
  549. if(!fent)
  550. return E_FS_ERROR;
  551. strcat(ftable->ram0names[n], ftable->ram0dirname);
  552. strcat(ftable->ram0names[n], fep->name);
  553. newfile = CreateFile(ftable->ram0names[n], GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  554. if(newfile == INVALID_HANDLE_VALUE)
  555. return E_FS_ERROR;
  556. CloseHandle(newfile);
  557. memcpy(fent, fep, sizeof(WW_FENT_T));
  558. fent->count = 0;
  559. return E_FS_SUCCESS;
  560. }
  561. static WW_INT wwfs_unlink(WW_FS fs, char *fname) {
  562. WW_FENT_T *fent;
  563. WW_INT n;
  564. if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
  565. return E_FS_PERMISSION_DENIED;
  566. fent = findent(fs, fname, &n);
  567. if(!fent)
  568. return E_FS_FILE_NOT_FOUND;
  569. if(!DeleteFile(ftable->ram0names[n]))
  570. return E_FS_ERROR;
  571. fent->count = (WW_INT)-1;
  572. return E_FS_SUCCESS;
  573. }
  574. static WW_INT wwfs_newfs(WW_FS fs) {
  575. return E_FS_ERROR;
  576. }
  577. static WW_INT wwfs_defrag(WW_FS fs) {
  578. return E_FS_SUCCESS;
  579. }
  580. static WW_LONG wwfs_space(WW_FS fs) {
  581. return 0x7fffffff;
  582. }
  583. static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n) {
  584. int n_entries;
  585. WW_FENT_T *fents;
  586. int i;
  587. if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
  588. n_entries = ROOTFS_NUM_ENTRIES;
  589. fents = mmvm->swork->_root_fs_entries;
  590. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
  591. n_entries = ROM0FS_NUM_ENTRIES;
  592. fents = mmvm->swork->_rom0_fs_entries;
  593. } else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
  594. n_entries = RAM0FS_NUM_ENTRIES;
  595. fents = mmvm->swork->_ram0_fs_entries;
  596. } else {
  597. return NULL;
  598. }
  599. for(i = 0; i < n_entries; i++) {
  600. if(fents[i].count != -1 && !strncmp(fname, fents[i].name, MAXPATHLEN)) {
  601. *n = i;
  602. return &fents[i];
  603. }
  604. }
  605. return NULL;
  606. }
  607. static void InitFent(WW_FS fent) {
  608. strcpy(fent->name, "");
  609. strcpy(fent->info, "");
  610. fent->loc = 0;
  611. fent->len = 0;
  612. fent->count = (WW_INT)-1;
  613. fent->mode = 0;
  614. fent->mtime = 0;
  615. fent->handler.appid = 0;
  616. fent->resource = 0xffffffff;
  617. }