1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - FS - libraries
3   File:     fs_file.c
4 
5   Copyright 2007-2009 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2010-07-02#$
14   $Rev: 11351 $
15   $Author: okubata_ryoma $
16 
17  *---------------------------------------------------------------------------*/
18 
19 
20 #include <nitro/types.h>
21 #include <nitro/misc.h>
22 #include <nitro/mi.h>
23 #include <nitro/os.h>
24 #include <nitro/pxi.h>
25 #include <nitro/std/string.h>
26 #include <nitro/std/unicode.h>
27 #include <nitro/math/math.h>
28 
29 #include <nitro/fs.h>
30 
31 #include "../include/rom.h"
32 #include "../include/util.h"
33 #include "../include/command.h"
34 
35 
36 #define FS_DEBUG_TRACE(...) (void)0
37 //#define FS_DEBUG_TRACE  OS_TPrintf
38 
39 
40 /*---------------------------------------------------------------------------*/
41 /* functions */
42 
43 #if defined(FS_IMPLEMENT)
44 
45 /*---------------------------------------------------------------------------*
46   Name:         FSi_IsValidTransferRegion
47 
48   Description:  Read/Write����Ɏg�p����o�b�t�@���댯�Ȕ͈͂łȂ����ȈՔ���B
49 
50   Arguments:    buffer : �]���ΏۂƂȂ�o�b�t�@�B
51                 length : �]���T�C�Y�B
52 
53   Returns:      pos��1�����߂����Q�ƈʒu��-1�B
54  *---------------------------------------------------------------------------*/
FSi_IsValidTransferRegion(const void * buffer,s32 length)55 static BOOL FSi_IsValidTransferRegion(const void *buffer, s32 length)
56 {
57     BOOL    retval = FALSE;
58     if (buffer == NULL)
59     {
60         OS_TWarning("specified transfer buffer is NULL.\n");
61     }
62     else if (((u32)buffer >= HW_IOREG) && ((u32)buffer < HW_IOREG_END))
63     {
64         OS_TWarning("specified transfer buffer is in I/O register %08X. (seems to be dangerous)\n", buffer);
65     }
66     else if (length < 0)
67     {
68         OS_TWarning("specified transfer size is minus. (%d)\n", length);
69     }
70     else
71     {
72 #if !defined(SDK_TWL)
73         s32     mainmem_size = HW_MAIN_MEM_EX_SIZE;
74 #else
75         s32     mainmem_size = OS_IsRunOnTwl() ? HW_TWL_MAIN_MEM_EX_SIZE : HW_MAIN_MEM_EX_SIZE;
76 #endif
77         if (length > mainmem_size)
78         {
79             OS_TWarning("specified transfer size is over mainmemory-size. (%d)\n", length);
80         }
81         else
82         {
83             retval = TRUE;
84         }
85     }
86     return retval;
87 }
88 
89 /*---------------------------------------------------------------------------*
90   Name:         FSi_DecrementSjisPosition
91 
92   Description:  Shift_JIS������̎Q�ƈʒu��1�������߂��B
93 
94   Arguments:    str              Shift_JIS������̐擪���w���|�C���^�B
95                 pos              ���݂̕�����Q�ƈʒu�B(�o�C�g�P��)
96 
97   Returns:      pos��1�����߂����Q�ƈʒu��-1�B
98  *---------------------------------------------------------------------------*/
FSi_DecrementSjisPosition(const char * str,int pos)99 int FSi_DecrementSjisPosition(const char *str, int pos)
100 {
101     // �܂�1�o�C�g�������͊m���ɖ߂�B
102     int     prev = --pos;
103     // Shift_JIS�̕�����؂�ƂȂ�̂̓V���O���o�C�g���㑱�o�C�g�ł���
104     // ��s�o�C�g�ƌ㑱�o�C�g���}�b�s���O���ꕔ���L���Ă��邽�߁A
105     // ��������s�o�C�g�Ɍ����邤���͕�����ʂ��m�肵�Ȃ��̂ł���ɖ߂�B
106     for (; (prev > 0) && STD_IsSjisLeadByte(str[prev - 1]); --prev)
107     {
108     }
109     // "������b"�̂悤�ɂ����܂��Ȍ㑱�o�C�g�����‘S�p����������ł�����
110     // 2�̔{�������]���ɖ߂��Ă��邽�߂����������B(2�̏�]�����)
111     return pos - ((pos - prev) & 1);
112 }
113 
114 /*---------------------------------------------------------------------------*
115   Name:         FSi_IncrementSjisPositionToSlash
116 
117   Description:  Shift_JIS������̎Q�ƈʒu��
118                 �f�B���N�g����؂蕶�����I�[�܂Ői�߂�B
119 
120   Arguments:    str              Shift_JIS������̐擪���w���|�C���^�B
121                 pos              ���݂̕�����Q�ƈʒu�B(�o�C�g�P��)
122 
123   Returns:      pos�ȍ~�Ɍ����ŏ��̃f�B���N�g����؂肩�I�[�̈ʒu�B
124  *---------------------------------------------------------------------------*/
FSi_IncrementSjisPositionToSlash(const char * str,int pos)125 int FSi_IncrementSjisPositionToSlash(const char *str, int pos)
126 {
127     while (str[pos] && !FSi_IsSlash((u8)str[pos]))
128     {
129         pos = FSi_IncrementSjisPosition(str, pos);
130     }
131     return pos;
132 }
133 
134 /*---------------------------------------------------------------------------*
135   Name:         FSi_DecrementSjisPositionToSlash
136 
137   Description:  Shift_JIS������̎Q�ƈʒu��
138                 �f�B���N�g����؂蕶�����擪�܂Ŗ߂��B
139 
140   Arguments:    str              Shift_JIS������̐擪���w���|�C���^�B
141                 pos              ���݂̕�����Q�ƈʒu�B(�o�C�g�P��)
142 
143   Returns:      pos�����Ɍ����ŏ��̃f�B���N�g����؂肩-1�B
144  *---------------------------------------------------------------------------*/
FSi_DecrementSjisPositionToSlash(const char * str,int pos)145 int FSi_DecrementSjisPositionToSlash(const char *str, int pos)
146 {
147     for (;;)
148     {
149         pos = FSi_DecrementSjisPosition(str, pos);
150         if ((pos < 0) || FSi_IsSlash((u8)str[pos]))
151         {
152             break;
153         }
154     }
155     return pos;
156 }
157 
158 /*---------------------------------------------------------------------------*
159   Name:         FSi_TrimSjisTrailingSlash
160 
161   Description:  Shift_JIS������̏I�[���f�B���N�g����؂蕶���ł���Ώ����B
162 
163   Arguments:    str              Shift_JIS������B
164 
165   Returns:      �������B
166  *---------------------------------------------------------------------------*/
FSi_TrimSjisTrailingSlash(char * str)167 int FSi_TrimSjisTrailingSlash(char *str)
168 {
169     int     length = STD_GetStringLength(str);
170     int     lastpos = FSi_DecrementSjisPosition(str, length);
171     if ((lastpos >= 0) && FSi_IsSlash((u8)str[lastpos]))
172     {
173         length = lastpos;
174         str[length] = '\0';
175     }
176     return length;
177 }
178 
179 /*---------------------------------------------------------------------------*
180   Name:         FSi_DecrementUnicodePosition
181 
182   Description:  Unicode������̎Q�ƈʒu��1�������߂��B
183 
184   Arguments:    str              Unicode������̐擪���w���|�C���^�B
185                 pos              ���݂̕�����Q�ƈʒu�B(�o�C�g�P��)
186 
187   Returns:      pos��1�����߂����Q�ƈʒu��-1�B
188  *---------------------------------------------------------------------------*/
FSi_DecrementUnicodePosition(const u16 * str,int pos)189 int FSi_DecrementUnicodePosition(const u16 *str, int pos)
190 {
191     // �܂�1�����������͊m���ɖ߂�B
192     int     prev = --pos;
193     // �L���ȃT���Q�[�g�y�A�������ꍇ�͂���1�����߂�B
194     if ((pos > 0) &&
195         ((str[pos - 1] >= 0xD800) && (str[pos - 1] <= 0xDC00)) &&
196         ((str[pos - 0] >= 0xDC00) && (str[pos - 0] <= 0xE000)))
197     {
198         --pos;
199     }
200     return pos;
201 }
202 
203 /*---------------------------------------------------------------------------*
204   Name:         FSi_DecrementUnicodePositionToSlash
205 
206   Description:  Unicode������̎Q�ƈʒu��
207                 �f�B���N�g����؂蕶�����擪�܂Ŗ߂��B
208 
209   Arguments:    str              Unicode������̐擪���w���|�C���^�B
210                 pos              ���݂̕�����Q�ƈʒu�B(�o�C�g�P��)
211 
212   Returns:      pos�����Ɍ����ŏ��̃f�B���N�g����؂肩-1�B
213  *---------------------------------------------------------------------------*/
FSi_DecrementUnicodePositionToSlash(const u16 * str,int pos)214 int FSi_DecrementUnicodePositionToSlash(const u16 *str, int pos)
215 {
216     for (;;)
217     {
218         pos = FSi_DecrementUnicodePosition(str, pos);
219         if ((pos < 0) || FSi_IsUnicodeSlash(str[pos]))
220         {
221             break;
222         }
223     }
224     return pos;
225 }
226 
227 /*---------------------------------------------------------------------------*
228   Name:         FS_InitFile
229 
230   Description:  FSFile�\���̂�������
231 
232   Arguments:    file        FSFile�\����
233 
234   Returns:      None.
235  *---------------------------------------------------------------------------*/
FS_InitFile(FSFile * file)236 void FS_InitFile(FSFile *file)
237 {
238     SDK_NULL_ASSERT(file);
239     {
240         file->arc = NULL;
241         file->userdata = NULL;
242         file->next = NULL;
243         OS_InitThreadQueue(file->queue);
244         file->stat = 0;
245         file->stat |= (FS_COMMAND_INVALID << FS_FILE_STATUS_CMD_SHIFT);
246         file->argument = NULL;
247         file->error = FS_RESULT_SUCCESS;
248     }
249 }
250 
251 /*---------------------------------------------------------------------------*
252   Name:         FS_CancelFile
253 
254   Description:  �����R�}���h�̃L�����Z����v������
255 
256   Arguments:    file        �t�@�C���n���h��
257 
258   Returns:      None.
259  *---------------------------------------------------------------------------*/
FS_CancelFile(FSFile * file)260 void FS_CancelFile(FSFile *file)
261 {
262     SDK_NULL_ASSERT(file);
263     SDK_ASSERT(FS_IsAvailable());
264     {
265         OSIntrMode bak_psr = OS_DisableInterrupts();
266         if (FS_IsBusy(file))
267         {
268             file->stat |= FS_FILE_STATUS_CANCEL;
269             file->arc->flag |= FS_ARCHIVE_FLAG_CANCELING;
270         }
271         (void)OS_RestoreInterrupts(bak_psr);
272     }
273 }
274 
275 /*---------------------------------------------------------------------------*
276   Name:         FS_CreateFile
277 
278   Description:  �t�@�C����������
279 
280   Arguments:    path        �p�X��
281                 mode        �A�N�Z�X���[�h
282 
283   Returns:      �t�@�C��������ɐ���������TRUE
284  *---------------------------------------------------------------------------*/
FS_CreateFile(const char * path,u32 permit)285 BOOL FS_CreateFile(const char *path, u32 permit)
286 {
287     BOOL    retval = FALSE;
288     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
289     SDK_NULL_ASSERT(path);
290     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
291     {
292         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
293         u32         baseid = 0;
294         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
295         if (arc)
296         {
297             FSFile                  file[1];
298             FSArgumentForCreateFile arg[1];
299             FS_InitFile(file);
300             file->arc = arc;
301             file->argument = arg;
302             arg->baseid = baseid;
303             arg->relpath = relpath;
304             arg->permit = permit;
305             retval = FSi_SendCommand(file, FS_COMMAND_CREATEFILE, TRUE);
306         }
307     }
308     return retval;
309 }
310 
311 /*---------------------------------------------------------------------------*
312   Name:         FS_DeleteFile
313 
314   Description:  �t�@�C�����폜����
315 
316   Arguments:    path        �p�X��
317 
318   Returns:      �t�@�C��������ɍ폜������TRUE
319  *---------------------------------------------------------------------------*/
FS_DeleteFile(const char * path)320 BOOL FS_DeleteFile(const char *path)
321 {
322     BOOL    retval = FALSE;
323     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
324     SDK_NULL_ASSERT(path);
325     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
326     {
327         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
328         u32         baseid = 0;
329         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
330         if (arc)
331         {
332             FSFile                  file[1];
333             FSArgumentForDeleteFile arg[1];
334             FS_InitFile(file);
335             file->arc = arc;
336             file->argument = arg;
337             arg->baseid = baseid;
338             arg->relpath = relpath;
339             retval = FSi_SendCommand(file, FS_COMMAND_DELETEFILE, TRUE);
340         }
341     }
342     return retval;
343 }
344 
345 /*---------------------------------------------------------------------------*
346   Name:         FS_RenameFile
347 
348   Description:  �t�@�C������ύX����
349 
350   Arguments:    src         �ϊ����̃t�@�C����
351                 dst         �ϊ���̃t�@�C����
352 
353   Returns:      �t�@�C����������ɕύX������TRUE
354  *---------------------------------------------------------------------------*/
FS_RenameFile(const char * src,const char * dst)355 BOOL FS_RenameFile(const char *src, const char *dst)
356 {
357     BOOL    retval = FALSE;
358     FS_DEBUG_TRACE( "%s(%s->%s)\n", __FUNCTION__, src, dst);
359     SDK_NULL_ASSERT(src);
360     SDK_NULL_ASSERT(dst);
361     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
362     {
363         char        relpath_src[FS_ARCHIVE_FULLPATH_MAX + 1];
364         char        relpath_dst[FS_ARCHIVE_FULLPATH_MAX + 1];
365         u32         baseid_src = 0;
366         u32         baseid_dst = 0;
367         FSArchive  *arc_src = FS_NormalizePath(src, &baseid_src, relpath_src);
368         FSArchive  *arc_dst = FS_NormalizePath(dst, &baseid_dst, relpath_dst);
369         if (arc_src != arc_dst)
370         {
371             OS_TWarning("cannot rename between defferent archives.\n");
372         }
373         else
374         {
375             FSFile                  file[1];
376             FSArgumentForRenameFile arg[1];
377             FS_InitFile(file);
378             file->arc = arc_src;
379             file->argument = arg;
380             arg->baseid_src = baseid_src;
381             arg->relpath_src = relpath_src;
382             arg->baseid_dst = baseid_dst;
383             arg->relpath_dst = relpath_dst;
384             retval = FSi_SendCommand(file, FS_COMMAND_RENAMEFILE, TRUE);
385         }
386     }
387     return retval;
388 }
389 
390 /*---------------------------------------------------------------------------*
391   Name:         FS_GetPathInfo
392 
393   Description:  �t�@�C���܂��̓f�B���N�g���̏����擾����
394 
395   Arguments:    path        �p�X��
396                 info        ���̊i�[��
397 
398   Returns:      ��������
399  *---------------------------------------------------------------------------*/
FS_GetPathInfo(const char * path,FSPathInfo * info)400 BOOL FS_GetPathInfo(const char *path, FSPathInfo *info)
401 {
402     BOOL    retval = FALSE;
403     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
404     SDK_NULL_ASSERT(path);
405     SDK_NULL_ASSERT(info);
406     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
407     {
408         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
409         u32         baseid = 0;
410         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
411         if (arc)
412         {
413             FSFile                      file[1];
414             FSArgumentForGetPathInfo    arg[1];
415             FS_InitFile(file);
416             file->arc = arc;
417             file->argument = arg;
418             arg->baseid = baseid;
419             arg->relpath = relpath;
420             arg->info = info;
421             retval = FSi_SendCommand(file, FS_COMMAND_GETPATHINFO, TRUE);
422         }
423     }
424     return retval;
425 }
426 
427 /*---------------------------------------------------------------------------*
428   Name:         FS_SetPathInfo
429 
430   Description:  �t�@�C������ݒ肷��
431 
432   Arguments:    path        �p�X��
433                 info        ���̊i�[��
434 
435   Returns:      ��������
436  *---------------------------------------------------------------------------*/
FS_SetPathInfo(const char * path,const FSPathInfo * info)437 BOOL FS_SetPathInfo(const char *path, const FSPathInfo *info)
438 {
439     BOOL    retval = FALSE;
440     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
441     SDK_NULL_ASSERT(path);
442     SDK_NULL_ASSERT(info);
443     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
444     {
445         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
446         u32         baseid = 0;
447         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
448         if (arc)
449         {
450             FSFile                      file[1];
451             FSArgumentForSetPathInfo    arg[1];
452             FS_InitFile(file);
453             file->arc = arc;
454             file->argument = arg;
455             arg->baseid = baseid;
456             arg->relpath = relpath;
457             arg->info = (FSPathInfo*)info; //info->attributes��FATFS_PROPERTY_CTRL_MASK���Ƃ�����
458             retval = FSi_SendCommand(file, FS_COMMAND_SETPATHINFO, TRUE);
459         }
460     }
461     return retval;
462 }
463 
464 /*---------------------------------------------------------------------------*
465   Name:         FS_CreateDirectory
466 
467   Description:  �f�B���N�g����������
468 
469   Arguments:    path        �p�X��
470                 mode        �A�N�Z�X���[�h
471 
472   Returns:      �f�B���N�g��������ɐ���������TRUE
473  *---------------------------------------------------------------------------*/
FS_CreateDirectory(const char * path,u32 permit)474 BOOL FS_CreateDirectory(const char *path, u32 permit)
475 {
476     BOOL    retval = FALSE;
477     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
478     SDK_NULL_ASSERT(path);
479     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
480     {
481         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
482         u32         baseid = 0;
483         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
484         if (arc)
485         {
486             FSFile                          file[1];
487             FSArgumentForCreateDirectory    arg[1];
488             FS_InitFile(file);
489             file->arc = arc;
490             file->argument = arg;
491             arg->baseid = baseid;
492             arg->relpath = relpath;
493             arg->permit = permit;
494             retval = FSi_SendCommand(file, FS_COMMAND_CREATEDIRECTORY, TRUE);
495         }
496     }
497     return retval;
498 }
499 
500 /*---------------------------------------------------------------------------*
501   Name:         FS_DeleteDirectory
502 
503   Description:  �f�B���N�g�����폜����
504 
505   Arguments:    path        �p�X��
506 
507   Returns:      �f�B���N�g��������ɍ폜������TRUE
508  *---------------------------------------------------------------------------*/
FS_DeleteDirectory(const char * path)509 BOOL FS_DeleteDirectory(const char *path)
510 {
511     BOOL    retval = FALSE;
512     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
513     SDK_NULL_ASSERT(path);
514     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
515     {
516         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
517         u32         baseid = 0;
518         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
519         if (arc)
520         {
521             FSFile                          file[1];
522             FSArgumentForDeleteDirectory    arg[1];
523             FS_InitFile(file);
524             file->arc = arc;
525             file->argument = arg;
526             arg->baseid = baseid;
527             arg->relpath = relpath;
528             retval = FSi_SendCommand(file, FS_COMMAND_DELETEDIRECTORY, TRUE);
529         }
530     }
531     return retval;
532 }
533 
534 /*---------------------------------------------------------------------------*
535   Name:         FS_RenameDirectory
536 
537   Description:  �f�B���N�g������ύX����
538 
539   Arguments:    src         �ϊ����̃f�B���N�g����
540                 dst         �ϊ���̃f�B���N�g����
541 
542   Returns:      �f�B���N�g����������ɕύX������TRUE
543  *---------------------------------------------------------------------------*/
FS_RenameDirectory(const char * src,const char * dst)544 BOOL FS_RenameDirectory(const char *src, const char *dst)
545 {
546     BOOL    retval = FALSE;
547     FS_DEBUG_TRACE( "%s(%s->%s)\n", __FUNCTION__, src, dst);
548     SDK_NULL_ASSERT(src);
549     SDK_NULL_ASSERT(dst);
550     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
551     {
552         char        relpath_src[FS_ARCHIVE_FULLPATH_MAX + 1];
553         char        relpath_dst[FS_ARCHIVE_FULLPATH_MAX + 1];
554         u32         baseid_src = 0;
555         u32         baseid_dst = 0;
556         FSArchive  *arc_src = FS_NormalizePath(src, &baseid_src, relpath_src);
557         FSArchive  *arc_dst = FS_NormalizePath(dst, &baseid_dst, relpath_dst);
558         if (arc_src != arc_dst)
559         {
560             OS_TWarning("cannot rename between defferent archives.\n");
561         }
562         else
563         {
564             FSFile                          file[1];
565             FSArgumentForRenameDirectory    arg[1];
566             FS_InitFile(file);
567             file->arc = arc_src;
568             file->argument = arg;
569             arg->baseid_src = baseid_src;
570             arg->relpath_src = relpath_src;
571             arg->baseid_dst = baseid_dst;
572             arg->relpath_dst = relpath_dst;
573             retval = FSi_SendCommand(file, FS_COMMAND_RENAMEDIRECTORY, TRUE);
574         }
575     }
576     return retval;
577 }
578 
579 /*---------------------------------------------------------------------------*
580   Name:         FSi_GetFullPath
581 
582   Description:  �w�肳�ꂽ�p�X���t���p�X�֕ϊ�����B
583 
584   Arguments:    dst         ����ꂽ�t���p�X���i�[����o�b�t�@�B
585                             FS_ARCHIVE_FULLPATH_MAX+1�o�C�g�ȏ�łȂ���΂Ȃ�Ȃ��B
586                 path        �t�@�C���܂��̓f�B���N�g���̃p�X���B
587 
588   Returns:      �t���p�X������Ɏ擾�ł����TRUE
589  *---------------------------------------------------------------------------*/
FSi_GetFullPath(char * dst,const char * path)590 static BOOL FSi_GetFullPath(char *dst, const char *path)
591 {
592     FSArchive  *arc = FS_NormalizePath(path, NULL, dst);
593     if (arc)
594     {
595         const char *arcname = FS_GetArchiveName(arc);
596         int     m = STD_GetStringLength(arcname);
597         int     n = STD_GetStringLength(dst);
598         (void)STD_MoveMemory(&dst[m + 2], &dst[0], (u32)n + 1);
599         (void)STD_MoveMemory(&dst[0], arcname, (u32)m);
600         dst[m + 0] = ':';
601         dst[m + 1] = '/';
602     }
603     return (arc != NULL);
604 }
605 
606 /*---------------------------------------------------------------------------*
607   Name:         FSi_ComplementDirectory
608 
609   Description:  �w�肳�ꂽ�p�X�Ɏ���S�Ă̐e�f�B���N�g���̑��݂��m�F���A
610                 ���݂��Ȃ��K�w�͎����I�ɐ������ĕ⊮����B
611 
612   Arguments:    path        �t�@�C���܂��̓f�B���N�g���̃p�X���B
613                             ������1�K�w��܂ł̃f�B���N�g����⊮����B
614                 autogen     �����������ꂽ�ŏ�ʃf�B���N�g�����L�^����o�b�t�@�B
615                             FS_ARCHIVE_FULLPATH_MAX+1�o�C�g�ȏ�łȂ���΂Ȃ�Ȃ��B
616                             ���ʂ̐��ۂɂ�����炸autogen�ɂ͌��ʂ��Ԃ���A
617                             ������ł���΂��łɑS�đ��݂��Ă������Ƃ������B
618 
619   Returns:      �f�B���N�g��������ɐ���������TRUE
620  *---------------------------------------------------------------------------*/
FSi_ComplementDirectory(const char * path,char * autogen)621 static BOOL FSi_ComplementDirectory(const char *path, char *autogen)
622 {
623     BOOL    retval = FALSE;
624     int     root = 0;
625     // ��������t���p�X���ɐ��K���B(�X�^�b�N�ߖ�̂���autogen���p)
626     char   *tmppath = autogen;
627     if (FSi_GetFullPath(tmppath, path))
628     {
629         int     length = STD_GetStringLength(tmppath);
630         if (length > 0)
631         {
632             int     pos = 0;
633             FS_DEBUG_TRACE("  trying to complete \"%s\"\n", tmppath);
634             // �I�[��"/"�͏����B
635             length = FSi_TrimSjisTrailingSlash(tmppath);
636             // �ʼn��w�̃G���g���͖����B
637             length = FSi_DecrementSjisPositionToSlash(tmppath, length);
638             // ���݂���Ő[�̊K�w��T���B
639             for (pos = length; pos >= 0;)
640             {
641                 FSPathInfo  info[1];
642                 BOOL        exists;
643                 tmppath[pos] = '\0';
644                 exists = FS_GetPathInfo(tmppath, info);
645                 FS_DEBUG_TRACE("    - \"%s\" is%s existent (result:%d)\n", tmppath, exists ? "" : " not",
646                                FS_GetArchiveResultCode(tmppath));
647                 tmppath[pos] = '/';
648                 // �G���g�������݂��Ȃ���΂���ɏ�ʂ̊K�w�ցB
649                 if (!exists)
650                 {
651                     pos = FSi_DecrementSjisPositionToSlash(tmppath, pos);
652                 }
653                 // �������݂��Ă���΂ЂƂ܂������ŒT���I���B
654                 else
655                 {
656                     // �����̃t�@�C�������݂��Ă���ꍇ�͊m���Ɏ��s�B
657                     if ((info->attributes & FS_ATTRIBUTE_IS_DIRECTORY) == 0)
658                     {
659                         pos = -1;
660                     }
661                     // �����̃f�B���N�g�������݂��Ă���΂��̉��w��������������B
662                     else
663                     {
664                         ++pos;
665                     }
666                     break;
667                 }
668             }
669             // ��_�����߂�ꂽ�Ȃ�΂���ȍ~�̊K�w���J��Ԃ������B
670             if (pos >= 0)
671             {
672                 for (;;)
673                 {
674                     // �I�[�ɒB�����琬���B
675                     if (pos >= length)
676                     {
677                         retval = TRUE;
678                         break;
679                     }
680                     else
681                     {
682                         pos = FSi_IncrementSjisPositionToSlash(tmppath, pos);
683                         tmppath[pos] = '\0';
684                         if (!FS_CreateDirectory(tmppath, FS_PERMIT_R | FS_PERMIT_W))
685                         {
686                             break;
687                         }
688                         else
689                         {
690                             // �ŏ�ʂ̊K�w�͋L�����Ă����B
691                             if (root == 0)
692                             {
693                                 FS_DEBUG_TRACE("    - we have created \"%s\" as root\n", tmppath);
694                                 root = pos;
695                             }
696                             tmppath[pos++] = '/';
697                         }
698                     }
699                 }
700             }
701         }
702     }
703     // �����������ꂽ�ŏ�ʃf�B���N�g�����L�^�B
704     autogen[root] = '\0';
705     return retval;
706 }
707 
708 /*---------------------------------------------------------------------------*
709   Name:         FS_CreateFileAuto
710 
711   Description:  �K�v�Ȓ��ԃf�B���N�g�����܂߂ăt�@�C����������
712 
713   Arguments:    path        �p�X��
714                 permit      �A�N�Z�X���[�h
715 
716   Returns:      �t�@�C��������ɐ���������TRUE
717  *---------------------------------------------------------------------------*/
FS_CreateFileAuto(const char * path,u32 permit)718 BOOL FS_CreateFileAuto(const char *path, u32 permit)
719 {
720     BOOL    result = FALSE;
721     char    autogen[FS_ARCHIVE_FULLPATH_MAX + 1];
722     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
723     if (FSi_ComplementDirectory(path, autogen))
724     {
725         result = FS_CreateFile(path, permit);
726         if (!result)
727         {
728             (void)FS_DeleteDirectoryAuto(autogen);
729         }
730     }
731     return result;
732 }
733 
734 /*---------------------------------------------------------------------------*
735   Name:         FS_DeleteFileAuto
736 
737   Description:  �K�v�Ȓ��ԃf�B���N�g�����܂߂ăt�@�C�����폜����
738 
739   Arguments:    path        �p�X��
740 
741   Returns:      �t�@�C��������ɍ폜������TRUE
742  *---------------------------------------------------------------------------*/
FS_DeleteFileAuto(const char * path)743 BOOL FS_DeleteFileAuto(const char *path)
744 {
745     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
746     // �����̓��ꐫ�̂��߂ɑ��݂��Ă��邪���ۂɂ͕⊮�������s�v�B
747     return FS_DeleteFile(path);
748 }
749 
750 /*---------------------------------------------------------------------------*
751   Name:         FS_RenameFileAuto
752 
753   Description:  �K�v�Ȓ��ԃf�B���N�g�����܂߂ăt�@�C������ύX����
754 
755   Arguments:    src         �ϊ����̃t�@�C����
756                 dst         �ϊ���̃t�@�C����
757 
758   Returns:      �t�@�C����������ɕύX������TRUE
759  *---------------------------------------------------------------------------*/
FS_RenameFileAuto(const char * src,const char * dst)760 BOOL FS_RenameFileAuto(const char *src, const char *dst)
761 {
762     BOOL    result = FALSE;
763     char    autogen[FS_ARCHIVE_FULLPATH_MAX + 1];
764     FS_DEBUG_TRACE( "%s(%s->%s)\n", __FUNCTION__);
765     if (FSi_ComplementDirectory(dst, autogen))
766     {
767         result = FS_RenameFile(src, dst);
768         if (!result)
769         {
770             (void)FS_DeleteDirectoryAuto(autogen);
771         }
772     }
773     return result;
774 }
775 
776 /*---------------------------------------------------------------------------*
777   Name:         FS_CreateDirectoryAuto
778 
779   Description:  �K�v�Ȓ��ԃf�B���N�g�����܂߂ăf�B���N�g����������
780 
781   Arguments:    path        ��������f�B���N�g����
782                 permit      �A�N�Z�X���[�h
783 
784   Returns:      �f�B���N�g��������ɐ���������TRUE
785  *---------------------------------------------------------------------------*/
FS_CreateDirectoryAuto(const char * path,u32 permit)786 BOOL FS_CreateDirectoryAuto(const char *path, u32 permit)
787 {
788     BOOL    result = FALSE;
789     char    autogen[FS_ARCHIVE_FULLPATH_MAX + 1];
790     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
791     if (FSi_ComplementDirectory(path, autogen))
792     {
793         result = FS_CreateDirectory(path, permit);
794         if (!result)
795         {
796             (void)FS_DeleteDirectoryAuto(autogen);
797         }
798     }
799     return result;
800 }
801 
802 /*---------------------------------------------------------------------------*
803   Name:         FS_DeleteDirectoryAuto
804 
805   Description:  �f�B���N�g�����ċA�I�ɍ폜����
806 
807   Arguments:    path        �p�X��
808 
809   Returns:      �f�B���N�g��������ɍ폜������TRUE
810  *---------------------------------------------------------------------------*/
FS_DeleteDirectoryAuto(const char * path)811 BOOL FS_DeleteDirectoryAuto(const char *path)
812 {
813     BOOL    retval = FALSE;
814     FS_DEBUG_TRACE( "%s(%s)\n", __FUNCTION__, path);
815     if (path && *path)
816     {
817         char    tmppath[FS_ARCHIVE_FULLPATH_MAX + 1];
818         if (FSi_GetFullPath(tmppath, path))
819         {
820             int     pos;
821             BOOL    mayBeEmpty;
822             int     length = FSi_TrimSjisTrailingSlash(tmppath);
823             FS_DEBUG_TRACE("  trying to force-delete \"%s\"\n", tmppath);
824             mayBeEmpty = TRUE;
825             for (pos = 0; pos >= 0;)
826             {
827                 BOOL    failure = FALSE;
828                 // �܂����ڂ��̃f�B���N�g�����폜���Ă݂Đ�������Ȃ�1�K�w��ցB
829                 tmppath[length + pos] = '\0';
830                 if (mayBeEmpty && (FS_DeleteDirectory(tmppath) ||
831                     (FS_GetArchiveResultCode(tmppath) == FS_RESULT_ALREADY_DONE)))
832                 {
833                     FS_DEBUG_TRACE("  -> succeeded to delete \"%s\"\n", tmppath);
834                     pos = FSi_DecrementSjisPositionToSlash(&tmppath[length], pos);
835                 }
836                 else
837                 {
838                     // �f�B���N�g�����J����悤�Ȃ�S�G���g������B
839                     FSFile  dir[1];
840                     FS_InitFile(dir);
841                     if (!FS_OpenDirectory(dir, tmppath, FS_FILEMODE_R))
842                     {
843                         FS_DEBUG_TRACE("  -> failed to delete & open \"%s\"\n", tmppath);
844                         failure = TRUE;
845                     }
846                     else
847                     {
848                         FSDirectoryEntryInfo    info[1];
849                         tmppath[length + pos] = '/';
850                         mayBeEmpty = TRUE;
851                         while (FS_ReadDirectory(dir, info))
852                         {
853                             (void)STD_CopyString(&tmppath[length + pos + 1], info->longname);
854                             // �t�@�C�������݂���΍폜�B
855                             if ((info->attributes & FS_ATTRIBUTE_IS_DIRECTORY) == 0)
856                             {
857                                 if (!FS_DeleteFile(tmppath))
858                                 {
859                                     FS_DEBUG_TRACE("  -> failed to delete file \"%s\"\n", tmppath);
860                                     failure = TRUE;
861                                     break;
862                                 }
863                                 FS_DEBUG_TRACE("  -> succeeded to delete \"%s\"\n", tmppath);
864                             }
865                             // "." �܂��� ".." �Ȃ疳���B
866                             else if ((STD_CompareString(info->longname, ".") == 0) ||
867                                      (STD_CompareString(info->longname, "..") == 0))
868                             {
869                             }
870                             // ��łȂ��f�B���N�g�������݂���΂���ɉ��w�ֈړ��B
871                             else if (!FS_DeleteDirectory(tmppath))
872                             {
873                                 pos += 1 + STD_GetStringLength(info->longname);
874                                 mayBeEmpty = FALSE;
875                                 break;
876                             }
877                         }
878                         (void)FS_CloseDirectory(dir);
879                     }
880                 }
881                 // �������ׂ����삳�����s�����ꍇ�͏������~�B(ALREADY_DONE�Ȃ�)
882                 if (failure)
883                 {
884                     break;
885                 }
886             }
887             retval = (pos < 0);
888         }
889     }
890     return retval;
891 }
892 
893 /*---------------------------------------------------------------------------*
894   Name:         FS_RenameDirectoryAuto
895 
896   Description:  �K�v�Ȓ��ԃf�B���N�g���������������ăf�B���N�g������ύX����
897 
898   Arguments:    src         �ϊ����̃f�B���N�g����
899                 dst         �ϊ���̃f�B���N�g����
900 
901   Returns:      �f�B���N�g����������ɕύX������TRUE
902  *---------------------------------------------------------------------------*/
FS_RenameDirectoryAuto(const char * src,const char * dst)903 BOOL FS_RenameDirectoryAuto(const char *src, const char *dst)
904 {
905     BOOL    result = FALSE;
906     char    autogen[FS_ARCHIVE_FULLPATH_MAX + 1];
907     FS_DEBUG_TRACE( "%s(%s->%s)\n", __FUNCTION__, src, dst);
908     if (FSi_ComplementDirectory(dst, autogen))
909     {
910         result = FS_RenameDirectory(src, dst);
911         if (!result)
912         {
913             (void)FS_DeleteDirectoryAuto(autogen);
914         }
915     }
916     return result;
917 }
918 
919 /*---------------------------------------------------------------------------*
920   Name:         FS_GetArchiveResource
921 
922   Description:  �w�肵���A�[�J�C�u�̃��\�[�X�����擾����
923 
924   Arguments:    path        �A�[�J�C�u�����ł���p�X��
925                 resource    �擾�������\�[�X���̊i�[��
926 
927   Returns:      ���\�[�X�������Ɏ擾�ł����TRUE
928  *---------------------------------------------------------------------------*/
FS_GetArchiveResource(const char * path,FSArchiveResource * resource)929 BOOL FS_GetArchiveResource(const char *path, FSArchiveResource *resource)
930 {
931     BOOL    retval = FALSE;
932     SDK_NULL_ASSERT(path);
933     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
934     {
935         FSArchive  *arc = FS_NormalizePath(path, NULL, NULL);
936         if (arc)
937         {
938             FSFile                          file[1];
939             FSArgumentForGetArchiveResource arg[1];
940             FS_InitFile(file);
941             file->arc = arc;
942             file->argument = arg;
943             arg->resource = resource;
944             retval = FSi_SendCommand(file, FS_COMMAND_GETARCHIVERESOURCE, TRUE);
945         }
946     }
947     return retval;
948 }
949 
950 /*---------------------------------------------------------------------------*
951   Name:         FSi_GetSpaceToCreateDirectoryEntries
952 
953   Description:  �t�@�C���̐����Ɠ����ɐ��������f�B���N�g���G���g���̗e�ʂ����ς���
954                 (�p�X���ɑ��݂���f�B���N�g�����V�K�ɍ쐬���邱�Ƃ�z�肷��)
955 
956   Arguments:    path                �����������t�@�C���̃p�X���B
957                 bytesPerCluster     �t�@�C���V�X�e����̃N���X�^������̃o�C�g���B
958 
959   Returns:      �e��
960  *---------------------------------------------------------------------------*/
FSi_GetSpaceToCreateDirectoryEntries(const char * path,u32 bytesPerCluster)961 u32 FSi_GetSpaceToCreateDirectoryEntries(const char *path, u32 bytesPerCluster)
962 {
963     static const u32    bytesPerEntry = 32UL;
964     static const u32    longnamePerEntry = 13UL;
965     // �t���p�X�Ȃ�X�L�[�����������‚Še�G���g�����•ʂɔ���B
966     const char         *root = STD_SearchString(path, ":");
967     const char         *current = (root != NULL) ? (root + 1) : path;
968     u32                 totalBytes = 0;
969     u32                 restBytesInCluster = 0;
970     current += (*current == '/');
971     while (*current)
972     {
973         BOOL    isShortName = FALSE;
974         u32     entries = 0;
975         // �G���g�����̒������Z�o�B
976         u32     len = (u32)FSi_IncrementSjisPositionToSlash(current, 0);
977         // 8.3�`���ŕ\���ł���G���g�������ǂ�������B
978 #if 0
979         // (TWL�ō̗p���Ă���FAT�h���C�o�͏�ɒ����t�@�C������ۑ�����̂�
980         //  ���ۂɂ͂����܂Ō����Ȕ��菈���͕K�v�Ȃ�����)
981         {
982             static const char  *alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
983             static const char  *special = "!#$%&'()*+-<>?@^_`{}~";
984             if ((len <= 8 + 1 + 3) && STD_SearchChar(alnum, current[0]))
985             {
986                 u32     namelen = 0;
987                 u32     extlen = 0;
988                 u32     scanned = 0;
989                 for (; namelen < len; ++namelen)
990                 {
991                     char    c = current[scanned + namelen];
992                     if (!STD_SearchChar(alnum, c) && !STD_SearchChar(special, c))
993                     {
994                         break;
995                     }
996                 }
997                 scanned += namelen;
998                 if ((scanned < len) && (current[scanned] == '.'))
999                 {
1000                     ++scanned;
1001                     for (; scanned + extlen < len; ++extlen)
1002                     {
1003                         char    c = current[scanned + extlen];
1004                         if (!STD_SearchChar(alnum, c) && !STD_SearchChar(special, c))
1005                         {
1006                             break;
1007                         }
1008                     }
1009                     scanned += extlen;
1010                 }
1011                 if ((scanned == len) && (namelen <= 8) && (extlen <= 3))
1012                 {
1013                     isShortName = TRUE;
1014                 }
1015             }
1016         }
1017 #endif
1018         // 8.3�`���łȂ���Β����t�@�C�����̂��߂ɒlj��G���g�����K�v�B
1019         if (!isShortName)
1020         {
1021             entries += ((len + longnamePerEntry - 1UL) / longnamePerEntry);
1022         }
1023         // ������ɂ���1�G���g�����͏�ɏ�����Ƃ݂Ȃ��B
1024         entries += 1;
1025         current += len;
1026         // ���łɎ��������������f�B���N�g���̃N���X�^�]���ő���Ȃ��Ȃ�
1027         // ���ߕ��̃G���g�����N���X�^�P�ʂŏ����B
1028         {
1029             int     over = (int)(entries * bytesPerEntry - restBytesInCluster);
1030             if (over > 0)
1031             {
1032                 totalBytes += MATH_ROUNDUP(over, bytesPerCluster);
1033             }
1034         }
1035         // ����ɉ��w������Ȃ�f�B���N�g���Ƃ���1�N���X�^����A
1036         // ���̂��� "." ".." ��2�G���g�������������T�C�Y���]���ƂȂ�B
1037         if (*current != '\0')
1038         {
1039             current += 1;
1040             totalBytes += bytesPerCluster;
1041             restBytesInCluster = bytesPerCluster - (2 * bytesPerEntry);
1042         }
1043     }
1044     return totalBytes;
1045 }
1046 
1047 /*---------------------------------------------------------------------------*
1048   Name:         FS_HasEnoughSpaceToCreateFile
1049 
1050   Description:  �w�肵���p�X���ƃT�C�Y�����ƒt�@�C�������ݐ����”\�����肷��
1051 
1052   Arguments:    resource    ���O��FS_GetArchiveResource�֐��Ŏ擾�����A�[�J�C�u���B
1053                             �֐�����������ƁA�t�@�C��������镪�����e�T�C�Y����������B
1054                 path        �����������t�@�C���̃p�X���B
1055                 size        �����������t�@�C���̃T�C�Y�B
1056 
1057   Returns:      �w�肵���p�X���ƃT�C�Y�����ƒt�@�C���������”\�ł����TRUE
1058  *---------------------------------------------------------------------------*/
FS_HasEnoughSpaceToCreateFile(FSArchiveResource * resource,const char * path,u32 size)1059 BOOL FS_HasEnoughSpaceToCreateFile(FSArchiveResource *resource, const char *path, u32 size)
1060 {
1061     BOOL    retval = FALSE;
1062     u32 bytesPerCluster = resource->bytesPerSector * resource->sectorsPerCluster;
1063     if (bytesPerCluster != 0)
1064     {
1065         u32     needbytes = (FSi_GetSpaceToCreateDirectoryEntries(path, bytesPerCluster) +
1066                              MATH_ROUNDUP(size, bytesPerCluster));
1067         u32     needclusters = needbytes / bytesPerCluster;
1068         if (needclusters <= resource->availableClusters)
1069         {
1070             resource->availableClusters -= needclusters;
1071             resource->availableSize -= needbytes;
1072             retval = TRUE;
1073         }
1074     }
1075     return retval;
1076 }
1077 
1078 /*---------------------------------------------------------------------------*
1079   Name:         FS_IsArchiveReady
1080 
1081   Description:  �w�肵���A�[�J�C�u�����ݎg�p�”\�����肷��
1082 
1083   Arguments:    path        "�A�[�J�C�u��:"�Ŏn�܂��΃p�X
1084 
1085   Returns:      �w�肵���A�[�J�C�u�����ݎg�p�”\�ł����TRUE�B
1086                 �X���b�g�ɑ}������Ă��Ȃ�SD�������J�[�h�A�[�J�C�u��
1087                 �܂��C���|�[�g����Ă��Ȃ��Z�[�u�f�[�^�A�[�J�C�u�Ȃ�FALSE�B
1088  *---------------------------------------------------------------------------*/
FS_IsArchiveReady(const char * path)1089 BOOL FS_IsArchiveReady(const char *path)
1090 {
1091     FSArchiveResource   resource[1];
1092     return FS_GetArchiveResource(path, resource);
1093 }
1094 
1095 /*---------------------------------------------------------------------------*
1096   Name:         FS_FlushFile
1097 
1098   Description:  �t�@�C���̕ύX���e���f�o�C�X�֔��f����
1099 
1100   Arguments:    file        �t�@�C���n���h��
1101 
1102   Returns:      ��������
1103  *---------------------------------------------------------------------------*/
FS_FlushFile(FSFile * file)1104 FSResult FS_FlushFile(FSFile *file)
1105 {
1106     FSResult    retval = FS_RESULT_ERROR;
1107     SDK_NULL_ASSERT(file);
1108     SDK_ASSERT(FS_IsFile(file));
1109     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1110     {
1111         (void)FSi_SendCommand(file, FS_COMMAND_FLUSHFILE, TRUE);
1112         retval = FS_GetResultCode(file);
1113     }
1114     return retval;
1115 }
1116 
1117 /*---------------------------------------------------------------------------*
1118   Name:         FS_SetFileLength
1119 
1120   Description:  �t�@�C���T�C�Y��ύX����
1121 
1122   Arguments:    file        �t�@�C���n���h��
1123                 length      �ύX��̃T�C�Y
1124 
1125   Returns:      ��������
1126  *---------------------------------------------------------------------------*/
FS_SetFileLength(FSFile * file,u32 length)1127 FSResult FS_SetFileLength(FSFile *file, u32 length)
1128 {
1129     FSResult    retval = FS_RESULT_ERROR;
1130     SDK_NULL_ASSERT(file);
1131     SDK_ASSERT(FS_IsFile(file));
1132     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1133     {
1134         FSArgumentForSetFileLength  arg[1];
1135         file->argument = arg;
1136         arg->length = length;
1137         (void)FSi_SendCommand(file, FS_COMMAND_SETFILELENGTH, TRUE);
1138         retval = FS_GetResultCode(file);
1139     }
1140     return retval;
1141 }
1142 
1143 /*---------------------------------------------------------------------------*
1144   Name:         FS_GetPathName
1145 
1146   Description:  �w�肵���n���h���̃p�X�����擾����
1147 
1148   Arguments:    file        �t�@�C���܂��̓f�B���N�g��
1149                 buffer      �p�X�i�[��
1150                 length      �o�b�t�@�T�C�Y
1151 
1152   Returns:      ���������TRUE
1153  *---------------------------------------------------------------------------*/
FS_GetPathName(FSFile * file,char * buffer,u32 length)1154 BOOL FS_GetPathName(FSFile *file, char *buffer, u32 length)
1155 {
1156     BOOL    retval = FALSE;
1157     SDK_ASSERT(FS_IsAvailable());
1158     SDK_ASSERT(FS_IsFile(file) || FS_IsDir(file));
1159     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1160     {
1161         FSArgumentForGetPath    arg[1];
1162         file->argument = arg;
1163         arg->is_directory = FS_IsDir(file);
1164         arg->buffer = buffer;
1165         arg->length = length;
1166         retval = FSi_SendCommand(file, FS_COMMAND_GETPATH, TRUE);
1167     }
1168     return retval;
1169 }
1170 
1171 /*---------------------------------------------------------------------------*
1172   Name:         FS_GetPathLength
1173 
1174   Description:  �w�肵���t�@�C���܂��̓f�B���N�g���̃t���p�X���̒������擾
1175 
1176   Arguments:    file        �t�@�C���܂��̓f�B���N�g���n���h��
1177 
1178   Returns:      ��������ΏI�[��'\0'���܂߂��p�X���̒����A���s�����-1
1179  *---------------------------------------------------------------------------*/
FS_GetPathLength(FSFile * file)1180 s32 FS_GetPathLength(FSFile *file)
1181 {
1182     s32     retval = -1;
1183     if (FS_GetPathName(file, NULL, 0))
1184     {
1185         retval = file->arg.getpath.total_len;
1186     }
1187     return retval;
1188 }
1189 
1190 /*---------------------------------------------------------------------------*
1191   Name:         FS_ConvertPathToFileID
1192 
1193   Description:  �p�X������t�@�C��ID���擾����
1194 
1195   Arguments:    p_fileid    FSFileID�̊i�[��
1196                 path        �p�X��
1197 
1198   Returns:      ���������TRUE
1199  *---------------------------------------------------------------------------*/
FS_ConvertPathToFileID(FSFileID * p_fileid,const char * path)1200 BOOL FS_ConvertPathToFileID(FSFileID *p_fileid, const char *path)
1201 {
1202     BOOL    retval = FALSE;
1203     SDK_NULL_ASSERT(p_fileid);
1204     SDK_NULL_ASSERT(path);
1205     SDK_ASSERT(FS_IsAvailable());
1206     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1207     {
1208         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
1209         u32         baseid = 0;
1210         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
1211         if (arc)
1212         {
1213             FSFile      file[1];
1214             FSArgumentForFindPath   arg[1];
1215             FS_InitFile(file);
1216             file->arc = arc;
1217             file->argument = arg;
1218             arg->baseid = baseid;
1219             arg->relpath = relpath;
1220             arg->target_is_directory = FALSE;
1221             if (FSi_SendCommand(file, FS_COMMAND_FINDPATH, TRUE))
1222             {
1223                 p_fileid->arc = arc;
1224                 p_fileid->file_id = arg->target_id;
1225                 retval = TRUE;
1226             }
1227         }
1228     }
1229     return retval;
1230 }
1231 
1232 /*---------------------------------------------------------------------------*
1233   Name:         FS_OpenFileDirect
1234 
1235   Description:  �A�[�J�C�u���̗̈���ڎw�肵�ăt�@�C�����J��
1236 
1237   Arguments:    file         �n���h������ێ�����FSFile
1238                 arc          �}�b�v���ɂȂ�A�[�J�C�u
1239                 image_top    �t�@�C���C���[�W�擪�̃I�t�Z�b�g
1240                 image_bottom �t�@�C���C���[�W�I�[�̃I�t�Z�b�g
1241                 id           �C�ӂɎw�肷��t�@�C��ID
1242 
1243   Returns:      ���������TRUE
1244  *---------------------------------------------------------------------------*/
FS_OpenFileDirect(FSFile * file,FSArchive * arc,u32 image_top,u32 image_bottom,u32 id)1245 BOOL FS_OpenFileDirect(FSFile *file, FSArchive *arc,
1246                        u32 image_top, u32 image_bottom, u32 id)
1247 {
1248     BOOL    retval = FALSE;
1249     SDK_NULL_ASSERT(file);
1250     SDK_NULL_ASSERT(arc);
1251     SDK_ASSERT(FS_IsAvailable());
1252     SDK_ASSERT(!FS_IsFile(file));
1253     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1254     {
1255         FSArgumentForOpenFileDirect arg[1];
1256         file->arc = arc;
1257         file->argument = arg;
1258         arg->id = id;
1259         arg->top = image_top;
1260         arg->bottom = image_bottom;
1261         arg->mode = 0;
1262         retval = FSi_SendCommand(file, FS_COMMAND_OPENFILEDIRECT, TRUE);
1263     }
1264     return retval;
1265 }
1266 
1267 /*---------------------------------------------------------------------------*
1268   Name:         FS_OpenFileFast
1269 
1270   Description:  ID���w�肵�ăt�@�C�����J��
1271 
1272   Arguments:    file         �n���h������ێ�����FSFile
1273                 id           �J���ׂ��t�@�C�����w��FSFileID
1274 
1275   Returns:      ���������TRUE
1276  *---------------------------------------------------------------------------*/
FS_OpenFileFast(FSFile * file,FSFileID id)1277 BOOL FS_OpenFileFast(FSFile *file, FSFileID id)
1278 {
1279     BOOL    retval = FALSE;
1280     SDK_NULL_ASSERT(file);
1281     SDK_ASSERT(FS_IsAvailable());
1282     SDK_ASSERT(!FS_IsFile(file));
1283     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1284     if (id.arc)
1285     {
1286         FSArgumentForOpenFileFast   arg[1];
1287         file->arc = id.arc;
1288         file->argument = arg;
1289         arg->id = id.file_id;
1290         arg->mode = 0;
1291         retval = FSi_SendCommand(file, FS_COMMAND_OPENFILEFAST, TRUE);
1292     }
1293     return retval;
1294 }
1295 
1296 /*---------------------------------------------------------------------------*
1297   Name:         FS_OpenFileEx
1298 
1299   Description:  �p�X�����w�肵�ăt�@�C�����J��
1300 
1301   Arguments:    file        FSFile�\����
1302                 path        �p�X��
1303 
1304   Returns:      ���������TRUE
1305  *---------------------------------------------------------------------------*/
FS_OpenFileEx(FSFile * file,const char * path,u32 mode)1306 BOOL FS_OpenFileEx(FSFile *file, const char *path, u32 mode)
1307 {
1308     BOOL    retval = FALSE;
1309     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1310     SDK_NULL_ASSERT(file);
1311     SDK_NULL_ASSERT(path);
1312     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1313 
1314     // FS_FILEMODE_L �Ɋւ���_���`�F�b�N�B
1315     // (creation���[�h�ŊJ���‚ƒT�C�Y����������Ӗ�������)
1316     if (((mode & FS_FILEMODE_L) != 0) &&
1317         ((mode & FS_FILEMODE_RW) == FS_FILEMODE_W))
1318     {
1319         OS_TWarning("\"FS_FILEMODE_WL\" seems useless.\n"
1320                     "(this means creating empty file and prohibiting any modifications)");
1321     }
1322     {
1323         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
1324         u32         baseid = 0;
1325         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
1326         if (arc)
1327         {
1328             FSArgumentForOpenFile   arg[1];
1329             FS_InitFile(file);
1330             file->arc = arc;
1331             file->argument = arg;
1332             arg->baseid = baseid;
1333             arg->relpath = relpath;
1334             arg->mode = mode;
1335             if (FSi_SendCommand(file, FS_COMMAND_OPENFILE, TRUE))
1336             {
1337                 retval = TRUE;
1338             }
1339             else
1340             {
1341                 file->arc = NULL;
1342             }
1343         }
1344     }
1345     return retval;
1346 }
1347 
1348 /*---------------------------------------------------------------------------*
1349   Name:         FS_CloseFile
1350 
1351   Description:  �t�@�C����‚���
1352 
1353   Arguments:    file        �t�@�C���n���h��
1354 
1355   Returns:      ���������TRUE
1356  *---------------------------------------------------------------------------*/
FS_CloseFile(FSFile * file)1357 BOOL FS_CloseFile(FSFile *file)
1358 {
1359     BOOL    retval = FALSE;
1360     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1361     SDK_NULL_ASSERT(file);
1362     SDK_ASSERT(FS_IsAvailable());
1363     SDK_ASSERT(FS_IsFile(file));
1364     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1365     {
1366         retval = FSi_SendCommand(file, FS_COMMAND_CLOSEFILE, TRUE);
1367     }
1368     return retval;
1369 }
1370 
1371 /*---------------------------------------------------------------------------*
1372   Name:         FS_GetSeekCacheSize
1373 
1374   Description:  �����t�V�[�N�p�̃t���L���b�V���ɕK�v�ȃo�b�t�@�T�C�Y�����߂�
1375 
1376   Arguments:    path
1377 
1378   Returns:      ��������΃T�C�Y�A���s�����0
1379  *---------------------------------------------------------------------------*/
FS_GetSeekCacheSize(const char * path)1380 u32 FS_GetSeekCacheSize(const char *path)
1381 {
1382     u32         retval = 0;
1383     // �t�@�C�������݂���Ȃ�T�C�Y���擾����B
1384     FSPathInfo  info;
1385     if (FS_GetPathInfo(path, &info) &&
1386         ((info.attributes & FS_ATTRIBUTE_IS_DIRECTORY) == 0))
1387     {
1388         // �Y������A�[�J�C�u��FAT�����擾�B
1389         FSArchiveResource   resource;
1390         if (FS_GetArchiveResource(path, &resource))
1391         {
1392             // ���ۂ�FAT�x�[�X�̃A�[�J�C�u�ł���΃L���b�V���T�C�Y���Z�o�B
1393             u32     bytesPerCluster = resource.sectorsPerCluster * resource.bytesPerSector;
1394             if (bytesPerCluster != 0)
1395             {
1396                 static const u32    fatBits = 32;
1397                 retval = (u32)((info.filesize + bytesPerCluster - 1) / bytesPerCluster) * ((fatBits + 4) / 8);
1398 				// �o�b�t�@�O����L���b�V�����C���ɐ��������邽�ߗ]����lj��B
1399                 retval += (u32)(HW_CACHE_LINE_SIZE * 2);
1400             }
1401         }
1402     }
1403     return retval;
1404 }
1405 
1406 /*---------------------------------------------------------------------------*
1407   Name:         FS_SetSeekCache
1408 
1409   Description:  �����t�V�[�N�p�̃L���b�V���o�b�t�@�����蓖�Ă�
1410 
1411   Arguments:    file        �t�@�C���n���h��
1412                 buf         �L���b�V���o�b�t�@
1413                 buf_size    �L���b�V���o�b�t�@�T�C�Y
1414 
1415   Returns:      ���������TRUE
1416  *---------------------------------------------------------------------------*/
FS_SetSeekCache(FSFile * file,void * buf,u32 buf_size)1417 BOOL FS_SetSeekCache(FSFile *file, void* buf, u32 buf_size)
1418 {
1419     FSArgumentForSetSeekCache    arg[1];
1420     BOOL     retval = FALSE;
1421     SDK_ASSERT(FS_IsAvailable());
1422     SDK_ASSERT(FS_IsFile(file));
1423 
1424     file->argument = arg;
1425     arg->buf      = buf;
1426     arg->buf_size = buf_size;
1427     retval = FSi_SendCommand(file, FS_COMMAND_SETSEEKCACHE, TRUE);
1428 
1429     return retval;
1430 }
1431 
1432 /*---------------------------------------------------------------------------*
1433   Name:         FS_GetFileLength
1434 
1435   Description:  �t�@�C���T�C�Y���擾
1436 
1437   Arguments:    file        �t�@�C���n���h��
1438 
1439   Returns:      �t�@�C���T�C�Y
1440  *---------------------------------------------------------------------------*/
FS_GetFileLength(FSFile * file)1441 u32 FS_GetFileLength(FSFile *file)
1442 {
1443     u32     retval = 0;
1444     SDK_ASSERT(FS_IsAvailable());
1445     SDK_ASSERT(FS_IsFile(file));
1446     // �A�[�J�C�u�v���V�[�W���̏ꍇ�͂��̏�Œ��ڎQ�Ɖ”\�B
1447     if (!FSi_GetFileLengthIfProc(file, &retval))
1448     {
1449         FSArgumentForGetFileLength    arg[1];
1450         file->argument = arg;
1451         arg->length = 0;
1452         if (FSi_SendCommand(file, FS_COMMAND_GETFILELENGTH, TRUE))
1453         {
1454             retval = arg->length;
1455         }
1456     }
1457     return retval;
1458 }
1459 
1460 /*---------------------------------------------------------------------------*
1461   Name:         FS_GetFilePosition
1462 
1463   Description:  �t�@�C���|�C���^�̌��݈ʒu���擾
1464 
1465   Arguments:    file        �t�@�C���n���h��
1466 
1467   Returns:      �t�@�C���|�C���^�̌��݈ʒu
1468  *---------------------------------------------------------------------------*/
FS_GetFilePosition(FSFile * file)1469 u32 FS_GetFilePosition(FSFile *file)
1470 {
1471     u32     retval = 0;
1472     SDK_ASSERT(FS_IsAvailable());
1473     SDK_ASSERT(FS_IsFile(file));
1474     // �A�[�J�C�u�v���V�[�W���̏ꍇ�͂��̏�Œ��ڎQ�Ɖ”\�B
1475     if (!FSi_GetFilePositionIfProc(file, &retval))
1476     {
1477         FSArgumentForGetFilePosition    arg[1];
1478         file->argument = arg;
1479         arg->position = 0;
1480         if (FSi_SendCommand(file, FS_COMMAND_GETFILEPOSITION, TRUE))
1481         {
1482             retval = arg->position;
1483         }
1484     }
1485     return retval;
1486 }
1487 
1488 /*---------------------------------------------------------------------------*
1489   Name:         FS_SeekFile
1490 
1491   Description:  �t�@�C���|�C���^���ړ�
1492 
1493   Arguments:    file        �t�@�C���n���h��
1494                 offset      �ړ���
1495                 origin      �ړ��N�_
1496 
1497   Returns:      ���������TRUE
1498  *---------------------------------------------------------------------------*/
FS_SeekFile(FSFile * file,s32 offset,FSSeekFileMode origin)1499 BOOL FS_SeekFile(FSFile *file, s32 offset, FSSeekFileMode origin)
1500 {
1501     BOOL    retval = FALSE;
1502     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1503     SDK_NULL_ASSERT(file);
1504     SDK_ASSERT(FS_IsAvailable());
1505     SDK_ASSERT(FS_IsFile(file));
1506     {
1507         FSArgumentForSeekFile   arg[1];
1508         file->argument = arg;
1509         arg->offset = (int)offset;
1510         arg->from = origin;
1511         retval = FSi_SendCommand(file, FS_COMMAND_SEEKFILE, TRUE);
1512     }
1513     return retval;
1514 }
1515 
1516 /*---------------------------------------------------------------------------*
1517   Name:         FS_ReadFile
1518 
1519   Description:  �t�@�C������f�[�^��ǂݏo��
1520 
1521   Arguments:    file        �t�@�C���n���h��
1522                 buffer      �]����o�b�t�@
1523                 length      �ǂݏo���T�C�Y
1524 
1525   Returns:      ��������Ύ��ۂɓǂݏo�����T�C�Y�A���s�����-1
1526  *---------------------------------------------------------------------------*/
FS_ReadFile(FSFile * file,void * buffer,s32 length)1527 s32 FS_ReadFile(FSFile *file, void *buffer, s32 length)
1528 {
1529     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1530     SDK_NULL_ASSERT(file);
1531     SDK_ASSERT(FSi_IsValidTransferRegion(buffer, length));
1532     SDK_ASSERT(FS_IsAvailable());
1533     SDK_ASSERT(FS_IsFile(file) && !FS_IsBusy(file));
1534     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1535     {
1536         FSArgumentForReadFile   arg[1];
1537         file->argument = arg;
1538         arg->buffer = buffer;
1539         arg->length = (u32)length;
1540         if (FSi_SendCommand(file, FS_COMMAND_READFILE, TRUE))
1541         {
1542             length = (s32)arg->length;
1543         }
1544         else
1545         {
1546             if( ( file->error == FS_RESULT_INVALID_PARAMETER ) || ( file->error == FS_RESULT_ERROR ) ) {
1547                 length = -1; //�����������[�h���Ȃ������ꍇ
1548             }else{
1549                 length = (s32)arg->length; //���[�h�����݂��ꍇ��-1�ȏ�̒l�������Ă���
1550             }
1551         }
1552     }
1553     return length;
1554 }
1555 
1556 /*---------------------------------------------------------------------------*
1557   Name:         FS_ReadFileAsync
1558 
1559   Description:  �t�@�C������f�[�^������I�ɓǂݏo��
1560 
1561   Arguments:    file        �t�@�C���n���h��
1562                 buffer      �]����o�b�t�@
1563                 length      �ǂݏo���T�C�Y
1564 
1565   Returns:      ��������ΒP��length�Ɠ����l�A���s�����-1
1566  *---------------------------------------------------------------------------*/
FS_ReadFileAsync(FSFile * file,void * buffer,s32 length)1567 s32 FS_ReadFileAsync(FSFile *file, void *buffer, s32 length)
1568 {
1569     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1570     SDK_NULL_ASSERT(file);
1571     SDK_ASSERT(FSi_IsValidTransferRegion(buffer, length));
1572     SDK_ASSERT(FS_IsAvailable());
1573     SDK_ASSERT(FS_IsFile(file) && !FS_IsBusy(file));
1574     // �A�[�J�C�u�v���V�[�W���̏ꍇ�͂��̏�ŃT�C�Y�␳
1575     {
1576         u32     end, pos;
1577         if (FSi_GetFilePositionIfProc(file, &pos) &&
1578             FSi_GetFileLengthIfProc(file, &end) &&
1579             (pos + length > end))
1580         {
1581             length = (s32)(end - pos);
1582         }
1583     }
1584     {
1585         FSArgumentForReadFile  *arg = (FSArgumentForReadFile*)file->reserved2;
1586         file->argument = arg;
1587         arg->buffer = buffer;
1588         arg->length = (u32)length;
1589         (void)FSi_SendCommand(file, FS_COMMAND_READFILE, FALSE);
1590     }
1591     return length;
1592 }
1593 
1594 /*---------------------------------------------------------------------------*
1595   Name:         FS_WriteFile
1596 
1597   Description:  �t�@�C���փf�[�^����������
1598 
1599   Arguments:    file        �t�@�C���n���h��
1600                 buffer      �]�����o�b�t�@
1601                 length      �������݃T�C�Y
1602 
1603   Returns:      ��������Ύ��ۂɏ��������T�C�Y�A���s�����-1
1604  *---------------------------------------------------------------------------*/
FS_WriteFile(FSFile * file,const void * buffer,s32 length)1605 s32 FS_WriteFile(FSFile *file, const void *buffer, s32 length)
1606 {
1607     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1608     SDK_NULL_ASSERT(file);
1609     SDK_ASSERT(FSi_IsValidTransferRegion(buffer, length));
1610     SDK_ASSERT(FS_IsAvailable());
1611     SDK_ASSERT(FS_IsFile(file) && !FS_IsBusy(file));
1612     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1613     {
1614         FSArgumentForWriteFile  arg[1];
1615         file->argument = arg;
1616         arg->buffer = buffer;
1617         arg->length = (u32)length;
1618         if (FSi_SendCommand(file, FS_COMMAND_WRITEFILE, TRUE))
1619         {
1620             length = (s32)arg->length;
1621         }
1622         else
1623         {
1624             if( file->error == FS_RESULT_INVALID_PARAMETER) {
1625                 length = -1; //�����������C�g���Ȃ������ꍇ
1626             }else{
1627                 length = (s32)arg->length; //���C�g�����݂��ꍇ��-1�ȏ�̒l�������Ă���
1628             }
1629         }
1630     }
1631     return length;
1632 }
1633 
1634 /*---------------------------------------------------------------------------*
1635   Name:         FS_WriteFileAsync
1636 
1637   Description:  �t�@�C���փf�[�^������I�ɏ�������
1638 
1639   Arguments:    file        �t�@�C���n���h��
1640                 buffer      �]�����o�b�t�@
1641                 length      �������݃T�C�Y
1642 
1643   Returns:      ��������ΒP��length�Ɠ����l�A���s�����-1
1644  *---------------------------------------------------------------------------*/
FS_WriteFileAsync(FSFile * file,const void * buffer,s32 length)1645 s32 FS_WriteFileAsync(FSFile *file, const void *buffer, s32 length)
1646 {
1647     SDK_NULL_ASSERT(file);
1648     SDK_ASSERT(FSi_IsValidTransferRegion(buffer, length));
1649     SDK_ASSERT(FS_IsAvailable());
1650     SDK_ASSERT(FS_IsFile(file) && !FS_IsBusy(file));
1651     // �A�[�J�C�u�v���V�[�W���̏ꍇ�͂��̏�ŃT�C�Y�␳
1652     {
1653         u32     end, pos;
1654         if (FSi_GetFilePositionIfProc(file, &pos) &&
1655             FSi_GetFileLengthIfProc(file, &end) &&
1656             (pos + length > end))
1657         {
1658             length = (s32)(end - pos);
1659         }
1660     }
1661     {
1662         FSArgumentForWriteFile *arg = (FSArgumentForWriteFile*)file->reserved2;
1663         file->argument = arg;
1664         arg->buffer = buffer;
1665         arg->length = (u32)length;
1666         (void)FSi_SendCommand(file, FS_COMMAND_WRITEFILE, FALSE);
1667     }
1668     return length;
1669 }
1670 
1671 /*---------------------------------------------------------------------------*
1672   Name:         FS_OpenDirectory
1673 
1674   Description:  �f�B���N�g���n���h�����J��
1675 
1676   Arguments:    file        FSFile�\����
1677                 path        �p�X��
1678                 mode        �A�N�Z�X���[�h
1679 
1680   Returns:      ���������TRUE
1681  *---------------------------------------------------------------------------*/
FS_OpenDirectory(FSFile * file,const char * path,u32 mode)1682 BOOL FS_OpenDirectory(FSFile *file, const char *path, u32 mode)
1683 {
1684     BOOL    retval = FALSE;
1685     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1686     SDK_NULL_ASSERT(path);
1687     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1688     {
1689         char        relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
1690         u32         baseid = 0;
1691         FSArchive  *arc = FS_NormalizePath(path, &baseid, relpath);
1692         if (arc)
1693         {
1694             FSArgumentForOpenDirectory  arg[1];
1695             FS_InitFile(file);
1696             file->arc = arc;
1697             file->argument = arg;
1698             arg->baseid = baseid;
1699             arg->relpath = relpath;
1700             arg->mode = mode;
1701             if (FSi_SendCommand(file, FS_COMMAND_OPENDIRECTORY, TRUE))
1702             {
1703                 retval = TRUE;
1704             }
1705             else
1706             {
1707                 file->arc = NULL;
1708             }
1709         }
1710     }
1711     return retval;
1712 }
1713 
1714 /*---------------------------------------------------------------------------*
1715   Name:         FS_CloseDirectory
1716 
1717   Description:  �f�B���N�g���n���h����‚���
1718 
1719   Arguments:    file        FSFile�\����
1720 
1721   Returns:      ���������TRUE
1722  *---------------------------------------------------------------------------*/
FS_CloseDirectory(FSFile * file)1723 BOOL FS_CloseDirectory(FSFile *file)
1724 {
1725     BOOL    retval = FALSE;
1726     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
1727     SDK_NULL_ASSERT(file);
1728     SDK_ASSERT(FS_IsAvailable());
1729     SDK_ASSERT(FS_IsDir(file));
1730     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1731     {
1732         if (FSi_SendCommand(file, FS_COMMAND_CLOSEDIRECTORY, TRUE))
1733         {
1734             retval = TRUE;
1735         }
1736     }
1737     return retval;
1738 }
1739 
1740 /*---------------------------------------------------------------------------*
1741   Name:         FS_ReadDirectory
1742 
1743   Description:  �f�B���N�g���̃G���g����1�‚����ǂݐi�߂�
1744 
1745   Arguments:    file        FSFile�\����
1746                 info        FSDirectoryEntryInfo�\����
1747 
1748   Returns:      ���������TRUE
1749  *---------------------------------------------------------------------------*/
FS_ReadDirectory(FSFile * file,FSDirectoryEntryInfo * info)1750 BOOL FS_ReadDirectory(FSFile *file, FSDirectoryEntryInfo *info)
1751 {
1752     BOOL    retval = FALSE;
1753     SDK_NULL_ASSERT(file);
1754     SDK_NULL_ASSERT(info);
1755     SDK_ASSERT(FS_IsAvailable());
1756     SDK_ASSERT(FS_IsDir(file));
1757     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1758     {
1759         FSArgumentForReadDirectory  arg[1];
1760         file->argument = arg;
1761         arg->info = info;
1762         MI_CpuFill8(info, 0x00, sizeof(info));
1763         info->id = FS_INVALID_FILE_ID;
1764         if (FSi_SendCommand(file, FS_COMMAND_READDIR, TRUE))
1765         {
1766             retval = TRUE;
1767         }
1768     }
1769     return retval;
1770 }
1771 
1772 /*---------------------------------------------------------------------------*
1773   Name:         FS_SeekDir
1774 
1775   Description:  �f�B���N�g���ʒu���w�肵�ĊJ��
1776 
1777   Arguments:    file        FSFile�\����
1778                 pos         FS_ReadDir��FS_TellDir�Ŏ擾�����f�B���N�g���ʒu
1779 
1780   Returns:      ����������TRUE
1781  *---------------------------------------------------------------------------*/
FS_SeekDir(FSFile * file,const FSDirPos * pos)1782 BOOL FS_SeekDir(FSFile *file, const FSDirPos *pos)
1783 {
1784     BOOL    retval = FALSE;
1785     SDK_NULL_ASSERT(file);
1786     SDK_NULL_ASSERT(pos);
1787     SDK_NULL_ASSERT(pos->arc);
1788     SDK_ASSERT(FS_IsAvailable());
1789     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1790     {
1791         FSArgumentForSeekDirectory  arg[1];
1792         arg->id = (u32)((pos->own_id << 0) | (pos->index << 16));
1793         arg->position = pos->pos;
1794         file->arc = pos->arc;
1795         file->argument = arg;
1796         if (FSi_SendCommand(file, FS_COMMAND_SEEKDIR, TRUE))
1797         {
1798             file->stat |= FS_FILE_STATUS_IS_DIR;
1799             retval = TRUE;
1800         }
1801     }
1802     return retval;
1803 }
1804 
1805 /*---------------------------------------------------------------------------*
1806   Name:         FS_TellDir
1807 
1808   Description:  �f�B���N�g���n���h�����猻�݂̃f�B���N�g���ʒu���擾
1809 
1810   Arguments:    dir         �f�B���N�g���n���h��
1811                 pos         �f�B���N�g���ʒu�̊i�[��
1812 
1813   Returns:      ���������TRUE
1814  *---------------------------------------------------------------------------*/
FS_TellDir(const FSFile * dir,FSDirPos * pos)1815 BOOL FS_TellDir(const FSFile *dir, FSDirPos *pos)
1816 {
1817     BOOL        retval = FALSE;
1818     SDK_NULL_ASSERT(dir);
1819     SDK_NULL_ASSERT(pos);
1820     SDK_ASSERT(FS_IsAvailable());
1821     SDK_ASSERT(FS_IsDir(dir));
1822     {
1823         *pos = dir->prop.dir.pos;
1824         retval = TRUE;
1825     }
1826     return retval;
1827 }
1828 
1829 /*---------------------------------------------------------------------------*
1830   Name:         FS_RewindDir
1831 
1832   Description:  �f�B���N�g���n���h���̗��ʒu��擪�֖߂�
1833 
1834   Arguments:    dir         �f�B���N�g���n���h��
1835 
1836   Returns:      ���������TRUE
1837  *---------------------------------------------------------------------------*/
FS_RewindDir(FSFile * dir)1838 BOOL FS_RewindDir(FSFile *dir)
1839 {
1840     BOOL        retval = FALSE;
1841     SDK_NULL_ASSERT(dir);
1842     SDK_ASSERT(FS_IsAvailable());
1843     SDK_ASSERT(FS_IsDir(dir));
1844     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
1845 
1846     {
1847         FSDirPos pos;
1848         pos.arc = dir->arc;
1849         pos.own_id = dir->prop.dir.pos.own_id;
1850         pos.pos = 0;
1851         pos.index = 0;
1852         retval = FS_SeekDir(dir, &pos);
1853     }
1854     return retval;
1855 }
1856 
1857 
1858 /*---------------------------------------------------------------------------*
1859  * Unicode support
1860  *---------------------------------------------------------------------------*/
1861 
1862 enum
1863 {
1864     FS_UNICODE_CONVSRC_ASCII,
1865     FS_UNICODE_CONVSRC_SHIFT_JIS,
1866     FS_UNICODE_CONVSRC_UNICODE
1867 };
1868 
1869 /*---------------------------------------------------------------------------*
1870   Name:         FSi_CopySafeUnicodeString
1871 
1872   Description:   �o�b�t�@�T�C�Y���m�F���‚•������Unicode�Ƃ��ăR�s�[�B
1873 
1874   Arguments:    dst           �]����o�b�t�@
1875                 dstlen        �]����T�C�Y
1876                 src           �]�����o�b�t�@
1877                 srclen        �]���敶���T�C�Y
1878                 srctype       �]�����̕����Z�b�g
1879                 stickyFailure �]�����̐؂�̂Ă��N��������FALSE
1880 
1881   Returns:      ���ۂɊi�[���ꂽ�������B
1882  *---------------------------------------------------------------------------*/
FSi_CopySafeUnicodeString(u16 * dst,int dstlen,const void * srcptr,int srclen,int srctype,BOOL * stickyFailure)1883 static int FSi_CopySafeUnicodeString(u16 *dst, int dstlen,
1884                                      const void *srcptr, int srclen,
1885                                      int srctype, BOOL *stickyFailure)
1886 {
1887     int     srcpos = 0;
1888     int     dstpos = 0;
1889     if (srctype == FS_UNICODE_CONVSRC_ASCII)
1890     {
1891         const char *src = (const char *)srcptr;
1892         int     n = (dstlen - 1 < srclen) ? (dstlen - 1) : srclen;
1893         while ((dstpos < n) && src[srcpos])
1894         {
1895             dst[dstpos++] = (u8)src[srcpos++];
1896         }
1897         if ((srcpos < srclen) && src[srcpos])
1898         {
1899             *stickyFailure = TRUE;
1900         }
1901     }
1902     else if (srctype == FS_UNICODE_CONVSRC_UNICODE)
1903     {
1904         const u16 *src = (const u16 *)srcptr;
1905         int     n = (dstlen - 1 < srclen) ? (dstlen - 1) : srclen;
1906         while ((dstpos < n) && src[srcpos])
1907         {
1908             dst[dstpos++] = src[srcpos++];
1909         }
1910         if ((srcpos < srclen) && src[srcpos])
1911         {
1912             *stickyFailure = TRUE;
1913         }
1914     }
1915     else if (srctype == FS_UNICODE_CONVSRC_SHIFT_JIS)
1916     {
1917         const char *src = (const char *)srcptr;
1918         srcpos = srclen;
1919         dstpos = dstlen - 1;
1920         (void)FSi_ConvertStringSjisToUnicode(dst, &dstpos, src, &srcpos, NULL);
1921         if ((srcpos < srclen) && src[srcpos])
1922         {
1923             *stickyFailure = TRUE;
1924         }
1925     }
1926     dst[dstpos] = L'\0';
1927     return dstpos;
1928 }
1929 
1930 /*---------------------------------------------------------------------------*
1931   Name:         FSi_NormalizePathWtoW
1932 
1933   Description:  Unicode�p�X���A�[�J�C�u���܂Ŋ܂�Unicode�t���p�X�֕ϊ��B
1934 
1935   Arguments:    path        ���K������Ă��Ȃ��p�X������
1936                 baseid      ��f�B���N�g��ID�̊i�[��܂���NULL
1937                 relpath     �ϊ���̃p�X���i�[��܂���NULL
1938 
1939   Returns:      �A�[�J�C�u�|�C���^�܂���NULL
1940  *---------------------------------------------------------------------------*/
1941 FSArchive* FSi_NormalizePathWtoW(const u16 *path, u32*baseid, u16 *relpath);
FSi_NormalizePathWtoW(const u16 * path,u32 * baseid,u16 * relpath)1942 FSArchive* FSi_NormalizePathWtoW(const u16 *path, u32*baseid, u16 *relpath)
1943 {
1944     FSArchive  *arc = NULL;
1945     int         pathlen = 0;
1946     int         pathmax = FS_ARCHIVE_FULLPATH_MAX + 1;
1947     BOOL        stickyFailure = FALSE;
1948     // �܂��R�}���h�ΏۂƂȂ�A�[�J�C�u�����B
1949     // �w�肳�ꂽUnicode�p�X����΃p�X�Ȃ�A�[�J�C�u���擾�B
1950     BOOL        absolute = FALSE;
1951     int         arcnameLen;
1952     for (arcnameLen = 0; arcnameLen < FS_ARCHIVE_NAME_LONG_MAX + 1; ++arcnameLen)
1953     {
1954         if (path[arcnameLen] == L'\0')
1955         {
1956             break;
1957         }
1958         else if (FSi_IsUnicodeSlash(path[arcnameLen]))
1959         {
1960             break;
1961         }
1962         else if (path[arcnameLen] == L':')
1963         {
1964             char    arcname[FS_ARCHIVE_NAME_LONG_MAX + 1];
1965             int     j;
1966             for (j = 0; j < arcnameLen; ++j)
1967             {
1968                 arcname[j] = (char)path[j];
1969             }
1970             arcname[arcnameLen] = '\0';
1971             arc = FS_FindArchive(arcname, arcnameLen);
1972             break;
1973         }
1974     }
1975     if (arc)
1976     {
1977         absolute = TRUE;
1978         *baseid = 0;
1979     }
1980     else
1981     {
1982         arc = FS_NormalizePath("", baseid, NULL);
1983     }
1984     if (arc)
1985     {
1986         // �A�[�J�C�u��Unicode�Ή��”\�łȂ���΂����Ŏ��s�B
1987         u32     caps = 0;
1988         (void)arc->vtbl->GetArchiveCaps(arc, &caps);
1989         if ((caps & FS_ARCHIVE_CAPS_UNICODE) == 0)
1990         {
1991             arc = NULL;
1992         }
1993         else
1994         {
1995             // �擪�ɃA�[�J�C�u�����i�[�B
1996             pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
1997                                                  FS_GetArchiveName(arc), FS_ARCHIVE_NAME_LONG_MAX,
1998                                                  FS_UNICODE_CONVSRC_ASCII, &stickyFailure);
1999             pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2000                                                  L":", 1,
2001                                                  FS_UNICODE_CONVSRC_UNICODE, &stickyFailure);
2002             // ��΃p�X�Ȃ烋�[�g�ȉ������̂܂ܘA���B
2003             if (absolute)
2004             {
2005                 path += arcnameLen + 1 + FSi_IsUnicodeSlash(path[arcnameLen + 1]);
2006             }
2007             // �J�����g���[�g�Ȃ烋�[�g�ȉ����ژA���B
2008             else if (FSi_IsUnicodeSlash(*path))
2009             {
2010                 path += 1;
2011             }
2012             // �J�����g�f�B���N�g���Ȃ�Shift_JIS->Unicode�ϊ����ĘA���B
2013             else
2014             {
2015                 pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2016                                                      L"/", 1,
2017                                                      FS_UNICODE_CONVSRC_UNICODE, &stickyFailure);
2018                 pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2019                                                      FS_GetCurrentDirectory(), FS_ENTRY_LONGNAME_MAX,
2020                                                      FS_UNICODE_CONVSRC_SHIFT_JIS, &stickyFailure);
2021             }
2022             // �c��̕�����A���B
2023             pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2024                                                  L"/", 1,
2025                                                  FS_UNICODE_CONVSRC_UNICODE, &stickyFailure);
2026             {
2027                 // ����G���g�����ɒ��ӂ��‚‘��΃p�X���K���B
2028                 int     curlen = 0;
2029                 while (!stickyFailure)
2030                 {
2031                     u16     c = path[curlen];
2032                     if ((c != L'\0') && !FSi_IsUnicodeSlash(c))
2033                     {
2034                         curlen += 1;
2035                     }
2036                     else
2037                     {
2038                         // ��f�B���N�g���͖����B
2039                         if (curlen == 0)
2040                         {
2041                         }
2042                         // "." (�J�����g�f�B���N�g��)�͖����B
2043                         else if ((curlen == 1) && (path[0] == L'.'))
2044                         {
2045                         }
2046                         // ".." (�e�f�B���N�g��)�̓��[�g������Ƃ���1�K�w�オ��B
2047                         else if ((curlen == 2) && (path[0] == '.') && (path[1] == '.'))
2048                         {
2049                             if ((pathlen > 2) && (relpath[pathlen - 2] != L':'))
2050                             {
2051                                 --pathlen;
2052                                 pathlen = FSi_DecrementUnicodePositionToSlash(relpath, pathlen) + 1;
2053                             }
2054                         }
2055                         // ����ȊO�̓G���g���lj��B
2056                         else
2057                         {
2058                             pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2059                                                                  path, curlen,
2060                                                                  FS_UNICODE_CONVSRC_UNICODE, &stickyFailure);
2061                             if (c != L'\0')
2062                             {
2063                                 pathlen += FSi_CopySafeUnicodeString(&relpath[pathlen], pathmax - pathlen,
2064                                                                      L"/", 1,
2065                                                                      FS_UNICODE_CONVSRC_UNICODE, &stickyFailure);
2066                             }
2067                         }
2068                         if (c == L'\0')
2069                         {
2070                             break;
2071                         }
2072                         path += curlen + 1;
2073                         curlen = 0;
2074                     }
2075                 }
2076             }
2077             relpath[pathlen] = L'\0';
2078         }
2079     }
2080     return stickyFailure ? NULL : arc;
2081 }
2082 
2083 /*---------------------------------------------------------------------------*
2084   Name:         FS_OpenFileExW
2085 
2086   Description:  �p�X�����w�肵�ăt�@�C�����J��
2087 
2088   Arguments:    file        FSFile�\����
2089                 path        �p�X��
2090 
2091   Returns:      ���������TRUE
2092  *---------------------------------------------------------------------------*/
FS_OpenFileExW(FSFile * file,const u16 * path,u32 mode)2093 BOOL FS_OpenFileExW(FSFile *file, const u16 *path, u32 mode)
2094 {
2095     BOOL    retval = FALSE;
2096     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
2097     SDK_NULL_ASSERT(file);
2098     SDK_NULL_ASSERT(path);
2099     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
2100 
2101     // FS_FILEMODE_L �Ɋւ���_���`�F�b�N�B
2102     // (creation���[�h�ŊJ���‚ƒT�C�Y����������Ӗ�������)
2103     if (((mode & FS_FILEMODE_L) != 0) &&
2104         ((mode & FS_FILEMODE_RW) == FS_FILEMODE_W))
2105     {
2106         OS_TWarning("\"FS_FILEMODE_WL\" seems useless.\n"
2107                     "(this means creating empty file and prohibiting any modifications)");
2108     }
2109     {
2110         u16         relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
2111         u32         baseid = 0;
2112         FSArchive  *arc = FSi_NormalizePathWtoW(path, &baseid, relpath);
2113         // �����_�ł�Unicode���g�p�”\�ȍŏ��̕ύX�ɂƂǂ߂邽�߂�
2114         // ROM�Ȃ�Unicode��Ή��̃A�[�J�C�u�ł�Unsupported��Ԃ��B
2115         if (!arc)
2116         {
2117             file->error = FS_RESULT_UNSUPPORTED;
2118         }
2119         else
2120         {
2121             FSArgumentForOpenFile   arg[1];
2122             FS_InitFile(file);
2123             file->arc = arc;
2124             file->argument = arg;
2125             arg->baseid = baseid;
2126             arg->relpath = (char*)relpath;
2127             arg->mode = mode;
2128             file->stat |= FS_FILE_STATUS_UNICODE_MODE;
2129             if (FSi_SendCommand(file, FS_COMMAND_OPENFILE, TRUE))
2130             {
2131                 retval = TRUE;
2132             }
2133             else
2134             {
2135                 file->arc = NULL;
2136             }
2137         }
2138     }
2139     return retval;
2140 }
2141 
2142 /*---------------------------------------------------------------------------*
2143   Name:         FS_OpenDirectoryW
2144 
2145   Description:  �f�B���N�g���n���h�����J��
2146 
2147   Arguments:    file        FSFile�\����
2148                 path        �p�X��
2149                 mode        �A�N�Z�X���[�h
2150 
2151   Returns:      ���������TRUE
2152  *---------------------------------------------------------------------------*/
FS_OpenDirectoryW(FSFile * file,const u16 * path,u32 mode)2153 BOOL FS_OpenDirectoryW(FSFile *file, const u16 *path, u32 mode)
2154 {
2155     BOOL    retval = FALSE;
2156     FS_DEBUG_TRACE( "%s\n", __FUNCTION__);
2157     SDK_NULL_ASSERT(path);
2158     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
2159     {
2160         u16         relpath[FS_ARCHIVE_FULLPATH_MAX + 1];
2161         u32         baseid = 0;
2162         FSArchive  *arc = FSi_NormalizePathWtoW(path, &baseid, relpath);
2163         // �����_�ł�Unicode���g�p�”\�ȍŏ��̕ύX�ɂƂǂ߂邽�߂�
2164         // ROM�Ȃ�Unicode��Ή��̃A�[�J�C�u�ł�Unsupported��Ԃ��B
2165         if (!arc)
2166         {
2167             file->error = FS_RESULT_UNSUPPORTED;
2168         }
2169         else
2170         {
2171             FSArgumentForOpenDirectory  arg[1];
2172             FS_InitFile(file);
2173             file->arc = arc;
2174             file->argument = arg;
2175             arg->baseid = baseid;
2176             arg->relpath = (char*)relpath;
2177             arg->mode = mode;
2178             file->stat |= FS_FILE_STATUS_UNICODE_MODE;
2179             if (FSi_SendCommand(file, FS_COMMAND_OPENDIRECTORY, TRUE))
2180             {
2181                 retval = TRUE;
2182             }
2183             else
2184             {
2185                 file->arc = NULL;
2186             }
2187         }
2188     }
2189     return retval;
2190 }
2191 
2192 /*---------------------------------------------------------------------------*
2193   Name:         FS_ReadDirectoryW
2194 
2195   Description:  �f�B���N�g���̃G���g����1�‚����ǂݐi�߂�
2196 
2197   Arguments:    file        FSFile�\����
2198                 info        FSDirectoryEntryInfo�\����
2199 
2200   Returns:      ���������TRUE
2201  *---------------------------------------------------------------------------*/
FS_ReadDirectoryW(FSFile * file,FSDirectoryEntryInfoW * info)2202 BOOL FS_ReadDirectoryW(FSFile *file, FSDirectoryEntryInfoW *info)
2203 {
2204     BOOL    retval = FALSE;
2205     SDK_NULL_ASSERT(file);
2206     SDK_NULL_ASSERT(info);
2207     SDK_ASSERT(FS_IsAvailable());
2208     SDK_ASSERT(FS_IsDir(file));
2209     SDK_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
2210     {
2211         FSArchive  *arc = file->arc;
2212         // ���݂�Unicode���g�p�ł���ŏ��̕ύX�ɂƂǂ߂邽�߁A
2213         // ROM�Ȃ�Unicode��Ή��̃A�[�J�C�u�ł�Unsupported��Ԃ��B
2214         u32     caps = 0;
2215         (void)arc->vtbl->GetArchiveCaps(arc, &caps);
2216         if ((caps & FS_ARCHIVE_CAPS_UNICODE) == 0)
2217         {
2218             file->error = FS_RESULT_UNSUPPORTED;
2219         }
2220         else
2221         {
2222             FSArgumentForReadDirectory  arg[1];
2223             file->argument = arg;
2224             arg->info = (FSDirectoryEntryInfo*)info;
2225             MI_CpuFill8(info, 0x00, sizeof(info));
2226             info->id = FS_INVALID_FILE_ID;
2227             file->stat |= FS_FILE_STATUS_UNICODE_MODE;
2228             if (FSi_SendCommand(file, FS_COMMAND_READDIR, TRUE))
2229             {
2230                 retval = TRUE;
2231             }
2232         }
2233     }
2234     return retval;
2235 }
2236 
2237 
2238 /*---------------------------------------------------------------------------*
2239  * obsolete functions
2240  *---------------------------------------------------------------------------*/
2241 
2242 /*---------------------------------------------------------------------------*
2243   Name:         FSi_ConvertToDirEntry
2244 
2245   Description:  FSDirectoryEntryInfo�\���̂���FSDirEntry�\���̂ւ̕ϊ�
2246 
2247   Arguments:    entry       �ϊ����FSDirEntry�\����
2248                 arc         �ϊ����̏����擾�����A�[�J�C�u
2249                 info        �ϊ�����FSDirectoryEntryInfo�\����
2250 
2251   Returns:      ���������TRUE
2252  *---------------------------------------------------------------------------*/
FSi_ConvertToDirEntry(FSDirEntry * entry,FSArchive * arc,const FSDirectoryEntryInfo * info)2253 static void FSi_ConvertToDirEntry(FSDirEntry *entry, FSArchive *arc, const FSDirectoryEntryInfo *info)
2254 {
2255     entry->name_len = info->longname_length;
2256     if (entry->name_len > sizeof(entry->name) - 1)
2257     {
2258         entry->name_len = sizeof(entry->name) - 1;
2259     }
2260     MI_CpuCopy8(info->longname, entry->name, entry->name_len);
2261     entry->name[entry->name_len] = '\0';
2262     if (info->id == FS_INVALID_FILE_ID)
2263     {
2264         entry->is_directory = FALSE;
2265         entry->file_id.file_id = FS_INVALID_FILE_ID;
2266         entry->file_id.arc = NULL;
2267     }
2268     else if ((info->attributes & FS_ATTRIBUTE_IS_DIRECTORY) != 0)
2269     {
2270         entry->is_directory = TRUE;
2271         entry->dir_id.arc = arc;
2272         entry->dir_id.own_id = (u16)(info->id >> 0);
2273         entry->dir_id.index = (u16)(info->id >> 16);
2274         entry->dir_id.pos = 0;
2275     }
2276     else
2277     {
2278         entry->is_directory = FALSE;
2279         entry->file_id.file_id = info->id;
2280         entry->file_id.arc = arc;
2281     }
2282 }
2283 
2284 /*---------------------------------------------------------------------------*
2285   Name:         FS_OpenFile
2286 
2287   Description:  �p�X�����w�肵�ăt�@�C�����J��
2288 
2289   Arguments:    file        FSFile�\����
2290                 path        �p�X��
2291 
2292   Returns:      ���������TRUE
2293  *---------------------------------------------------------------------------*/
FS_OpenFile(FSFile * file,const char * path)2294 BOOL FS_OpenFile(FSFile *file, const char *path)
2295 {
2296     return FS_OpenFileEx(file, path, FS_FILEMODE_R);
2297 }
2298 
2299 /*---------------------------------------------------------------------------*
2300   Name:         FS_GetLength
2301 
2302   Description:  �t�@�C���T�C�Y���擾
2303 
2304   Arguments:    file        �t�@�C���n���h��
2305 
2306   Returns:      �t�@�C���T�C�Y
2307  *---------------------------------------------------------------------------*/
FS_GetLength(FSFile * file)2308 u32 FS_GetLength(FSFile *file)
2309 {
2310     return FS_GetFileLength(file);
2311 }
2312 
2313 /*---------------------------------------------------------------------------*
2314   Name:         FS_GetPosition
2315 
2316   Description:  �t�@�C���|�C���^�̌��݈ʒu���擾
2317 
2318   Arguments:    file        �t�@�C���n���h��
2319 
2320   Returns:      �t�@�C���|�C���^�̌��݈ʒu
2321  *---------------------------------------------------------------------------*/
FS_GetPosition(FSFile * file)2322 u32 FS_GetPosition(FSFile *file)
2323 {
2324     return FS_GetFilePosition(file);
2325 }
2326 
2327 /*---------------------------------------------------------------------------*
2328   Name:         FS_FindDir
2329 
2330   Description:  �f�B���N�g���n���h�����J��
2331 
2332   Arguments:    dir         FSFile�\����
2333                 path        �p�X��
2334 
2335   Returns:      ���������TRUE
2336  *---------------------------------------------------------------------------*/
FS_FindDir(FSFile * dir,const char * path)2337 BOOL FS_FindDir(FSFile *dir, const char *path)
2338 {
2339     return FS_OpenDirectory(dir, path, FS_FILEMODE_R);
2340 }
2341 
2342 /*---------------------------------------------------------------------------*
2343   Name:         FS_ReadDir
2344 
2345   Description:  �f�B���N�g���̃G���g����1�‚����ǂݐi�߂�
2346 
2347   Arguments:    file        FSFile�\����
2348                 entry       FSDirEntry�\����
2349 
2350   Returns:      ���������TRUE
2351  *---------------------------------------------------------------------------*/
FS_ReadDir(FSFile * file,FSDirEntry * entry)2352 BOOL FS_ReadDir(FSFile *file, FSDirEntry *entry)
2353 {
2354     BOOL                    retval = FALSE;
2355     FSDirectoryEntryInfo    info[1];
2356     if (FS_ReadDirectory(file, info))
2357     {
2358         FSi_ConvertToDirEntry(entry, FS_GetAttachedArchive(file), info);
2359         retval = TRUE;
2360     }
2361     return retval;
2362 }
2363 
2364 /*---------------------------------------------------------------------------*
2365   Name:         FS_ChangeDir
2366 
2367   Description:  �J�����g�f�B���N�g����ύX����
2368 
2369   Arguments:    path        �p�X��
2370 
2371   Returns:      ���������TRUE
2372  *---------------------------------------------------------------------------*/
FS_ChangeDir(const char * path)2373 BOOL    FS_ChangeDir(const char *path)
2374 {
2375     return FS_SetCurrentDirectory(path);
2376 }
2377 
2378 /*---------------------------------------------------------------------------*
2379   Name:         FS_GetFileInfo
2380 
2381   Description:  �t�@�C�������擾����
2382 
2383   Arguments:    path        �p�X��
2384                 info        ���̊i�[��
2385 
2386   Returns:      ��������
2387  *---------------------------------------------------------------------------*/
FS_GetFileInfo(const char * path,FSFileInfo * info)2388 FSResult FS_GetFileInfo(const char *path, FSFileInfo *info)
2389 {
2390     return FS_GetPathInfo(path, info) ? FS_RESULT_SUCCESS : FS_GetArchiveResultCode(path);
2391 }
2392 
2393 
2394 #endif /* FS_IMPLEMENT */
2395 
2396 // �ȉ���FS���C�u�����ȊO�ł��g�p�����̂�FS_IMPLEMENT�̑ΏۊO�B
2397 // ARM7�ł�Unicode�Ή����K�v�ɂȂ�̂�TWL���쎞�݂̂Ȃ̂Ŋg���������֔z�u�B
2398 #if defined(SDK_TWL) && defined(SDK_ARM7)
2399 #include <twl/ltdmain_begin.h>
2400 #endif
2401 
2402 static const int        FSiUnicodeBufferQueueMax = 4;
2403 static OSMessageQueue   FSiUnicodeBufferQueue[1];
2404 static OSMessage        FSiUnicodeBufferQueueArray[FSiUnicodeBufferQueueMax];
2405 static BOOL             FSiUnicodeBufferQueueInitialized = FALSE;
2406 static u16              FSiUnicodeBufferTable[FSiUnicodeBufferQueueMax][FS_ARCHIVE_FULLPATH_MAX + 1];
2407 
2408 /*---------------------------------------------------------------------------*
2409   Name:         FSi_GetUnicodeBuffer
2410 
2411   Description:  Unicode�ϊ��p�̈ꎞ�o�b�t�@���擾�B
2412                 FS���C�u������Shift_JIS��ϊ����邽�߂Ɏg�p�����B
2413 
2414   Arguments:    src : Unicode�ϊ��̕K�v��Shift_JIS������܂���NULL
2415 
2416   Returns:      �K�v�ɉ�����UTF16-LE�֕ϊ����ꂽ������o�b�t�@
2417  *---------------------------------------------------------------------------*/
FSi_GetUnicodeBuffer(const char * src)2418 u16* FSi_GetUnicodeBuffer(const char *src)
2419 {
2420     u16        *retval = NULL;
2421     // ����Ăяo�����Ƀo�b�t�@�����b�Z�[�W�L���[�֒lj��B
2422     OSIntrMode  bak = OS_DisableInterrupts();
2423     if (!FSiUnicodeBufferQueueInitialized)
2424     {
2425         int     i;
2426         FSiUnicodeBufferQueueInitialized = TRUE;
2427         OS_InitMessageQueue(FSiUnicodeBufferQueue, FSiUnicodeBufferQueueArray, 4);
2428         for (i = 0; i < FSiUnicodeBufferQueueMax; ++i)
2429         {
2430             (void)OS_SendMessage(FSiUnicodeBufferQueue, FSiUnicodeBufferTable[i], OS_MESSAGE_BLOCK);
2431         }
2432     }
2433     (void)OS_RestoreInterrupts(bak);
2434     // ���b�Z�[�W�L���[����o�b�t�@���m�ہB(������΂����Ńu���b�L���O)
2435     (void)OS_ReceiveMessage(FSiUnicodeBufferQueue, (OSMessage*)&retval, OS_MESSAGE_BLOCK);
2436     if (src)
2437     {
2438         int     dstlen = FS_ARCHIVE_FULLPATH_MAX;
2439         (void)FSi_ConvertStringSjisToUnicode(retval, &dstlen, src, NULL, NULL);
2440         retval[dstlen] = L'\0';
2441     }
2442     return retval;
2443 }
2444 
2445 /*---------------------------------------------------------------------------*
2446   Name:         FSi_ReleaseUnicodeBuffer
2447 
2448   Description:  Unicode�ϊ��p�̈ꎞ�o�b�t�@������B
2449 
2450   Arguments:    buf : FSi_GetUnicodeBuffer()�Ŋm�ۂ����o�b�t�@
2451 
2452   Returns:      None.
2453  *---------------------------------------------------------------------------*/
FSi_ReleaseUnicodeBuffer(const void * buf)2454 void FSi_ReleaseUnicodeBuffer(const void *buf)
2455 {
2456     if (buf)
2457     {
2458         // �g�p�����o�b�t�@�����b�Z�[�W�L���[�֕ԋp�B
2459         (void)OS_SendMessage(FSiUnicodeBufferQueue, (OSMessage)buf, OS_MESSAGE_BLOCK);
2460     }
2461 }
2462 
2463 /*---------------------------------------------------------------------------*
2464   Name:         FSi_ConvertStringSjisToUnicode
2465 
2466   Description:  ShiftJIS�������Unicode������ɕϊ��B
2467                 �����p�X�������炩��ASCII�݂̂ł���ꍇ�Ȃ�
2468                 Unicode��ShiftJIS�̑��ݕϊ����ȗ����ł���ꍇ��
2469                 ���̊֐����I�[�o�[���C�h���邱�Ƃɂ����
2470                 STD���C�u�����̕W�������������N�����̂�h�����Ƃ��ł���B
2471 
2472   Arguments:    dst               �ϊ���o�b�t�@.
2473                                   NULL ���w�肷��Ɗi�[�����͖��������.
2474                 dst_len           �ϊ���o�b�t�@�̍ő啶�������i�[���ēn��,
2475                                   ���ۂɊi�[���ꂽ�������������|�C���^.
2476                                   NULL ��^�����ꍇ�͖��������.
2477                 src               �ϊ����o�b�t�@.
2478                 src_len           �ϊ����ׂ��ő啶�������i�[���ēn��,
2479                                   ���ۂɕϊ����ꂽ�������������|�C���^.
2480                                   ���̎w�����������I�[�̈ʒu���D�悳���.
2481                                   ���̒l���i�[���ēn���� NULL ��^�����ꍇ��
2482                                   �I�[�ʒu�܂ł̕��������w�肵���Ƃ݂Ȃ����.
2483                 callback          �ϊ��ł��Ȃ����������ꂽ���ɌĂ΂��R�[���o�b�N.
2484                                   NULL���w�肵���ꍇ, �ϊ��ł��Ȃ������̈ʒu��
2485                                   �ϊ��������I������.
2486 
2487   Returns:      �ϊ������̌���.
2488  *---------------------------------------------------------------------------*/
2489 SDK_WEAK_SYMBOL
FSi_ConvertStringSjisToUnicode(u16 * dst,int * dst_len,const char * src,int * src_len,STDConvertUnicodeCallback callback)2490 STDResult FSi_ConvertStringSjisToUnicode(u16 *dst, int *dst_len,
2491                                          const char *src, int *src_len,
2492                                          STDConvertUnicodeCallback callback)
2493  __attribute__((never_inline))
2494 {
2495     return STD_ConvertStringSjisToUnicode(dst, dst_len, src, src_len, callback);
2496 }
2497 
2498 /*---------------------------------------------------------------------------*
2499   Name:         FSi_ConvertStringUnicodeToSjis
2500 
2501   Description:  Unicode�������ShiftJIS������ɕϊ��B
2502                 �����p�X�������炩��ASCII�݂̂ł���ꍇ�Ȃ�
2503                 Unicode��ShiftJIS�̑��ݕϊ����ȗ����ł���ꍇ��
2504                 ���̊֐����I�[�o�[���C�h���邱�Ƃɂ����
2505                 STD���C�u�����̕W�������������N�����̂�h�����Ƃ��ł���B
2506 
2507   Arguments:    dst               �ϊ���o�b�t�@.
2508                                   NULL ���w�肷��Ɗi�[�����͖��������.
2509                 dst_len           �ϊ���o�b�t�@�̍ő啶�������i�[���ēn��,
2510                                   ���ۂɊi�[���ꂽ�������������|�C���^.
2511                                   NULL ��^�����ꍇ�͖��������.
2512                 src               �ϊ����o�b�t�@.
2513                 src_len           �ϊ����ׂ��ő啶�������i�[���ēn��,
2514                                   ���ۂɕϊ����ꂽ�������������|�C���^.
2515                                   ���̎w�����������I�[�̈ʒu���D�悳���.
2516                                   ���̒l���i�[���ēn���� NULL ��^�����ꍇ��
2517                                   �I�[�ʒu�܂ł̕��������w�肵���Ƃ݂Ȃ����.
2518                 callback          �ϊ��ł��Ȃ����������ꂽ���ɌĂ΂��R�[���o�b�N.
2519                                   NULL���w�肵���ꍇ, �ϊ��ł��Ȃ������̈ʒu��
2520                                   �ϊ��������I������.
2521 
2522   Returns:      �ϊ������̌���.
2523  *---------------------------------------------------------------------------*/
2524 SDK_WEAK_SYMBOL
FSi_ConvertStringUnicodeToSjis(char * dst,int * dst_len,const u16 * src,int * src_len,STDConvertSjisCallback callback)2525 STDResult FSi_ConvertStringUnicodeToSjis(char *dst, int *dst_len,
2526                                          const u16 *src, int *src_len,
2527                                          STDConvertSjisCallback callback)
2528  __attribute__((never_inline))
2529 {
2530     return STD_ConvertStringUnicodeToSjis(dst, dst_len, src, src_len, callback);
2531 }
2532 
2533 #if defined(SDK_TWL) && defined(SDK_ARM7)
2534 #include <twl/ltdmain_end.h>
2535 #endif
2536