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