1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/DEMOLib
3   File:     DEMOHostio.c
4 
5   Copyright 2008 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:: 2008-11-19#$
14   $Rev: 9351 $
15   $Author: kitase_hirotake $
16  *---------------------------------------------------------------------------*/
17 
18 
19 #include <nitro.h>
20 #include "DEMOHostio.h"
21 
22 // Note that Host I/O can only be used when IS-TWL-DEBUGGER is the runtime environment and the IS-TWL-DEBUGGER library is present in both the compilation and linking environments.
23 // For example, suppose that the DEMOLib library is built separately from an application that uses it. If the IS-TWL-DEBUGGER software is not installed in one of those build environments, this module will simply generate code that outputs an error message.
24 //
25 //
26 //
27 #ifdef SDK_LINK_ISTD
28 #include <istdhio.h>
29 #include <istdfio.h>
30 
31 
32 /*---------------------------------------------------------------------------*/
33 /* Variables */
34 
35 #define DEMO_HIO_HANDLE_MAX   8
36 
37 // Wrapper archive for the IS-TWL-DEBUGGER Host I/O
38 typedef struct DEMOHIOContext
39 {
40     FSArchive       arc[1];
41     char            basepath[FS_ENTRY_LONGNAME_MAX];
42     char            fullpath[2][FS_ENTRY_LONGNAME_MAX];
43     ISTDFIOFile     file[DEMO_HIO_HANDLE_MAX];
44     ISTDFIOFindData ffdata[DEMO_HIO_HANDLE_MAX];
45     int             busyfiles;
46     int             validfiles;
47 }
48 DEMOHIOContext;
49 
50 static DEMOHIOContext DEMOiHIODrive[1] ATTRIBUTE_ALIGN(32);
51 
52 
53 /*---------------------------------------------------------------------------*/
54 /* Functions */
55 
56 // You cannot use Host I/O if the IS-TWL-DEBUGGER software is not installed in the linking environment, even if IS-TWL-DEBUGGER is the runtime environment.
57 // Prepare dummy functions to prevent link errors from occurring for programs that use DEMOLib but not Host I/O.
58 //
59 //
ISTDHIOInit(void)60 SDK_WEAK_SYMBOL void ISTDHIOInit(void) __attribute__((never_inline))
61 {
62 }
ISTDHIOOpen(u32)63 SDK_WEAK_SYMBOL BOOL ISTDHIOOpen(u32) __attribute__((never_inline))
64 {
65     OS_TWarning("cannot use HostI/O on this link-time environment.\n");
66     return FALSE;
67 }
ISTDFIOOpen(ISTDFIOFile *,const char *,u32)68 SDK_WEAK_SYMBOL u32 ISTDFIOOpen(ISTDFIOFile*, const char*, u32) __attribute__((never_inline))
69 {
70     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
71 }
ISTDFIOClose(ISTDFIOFile *)72 SDK_WEAK_SYMBOL u32 ISTDFIOClose(ISTDFIOFile*) __attribute__((never_inline))
73 {
74     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
75 }
ISTDFIORead(ISTDFIOFile *,void *,u32,u32 *)76 SDK_WEAK_SYMBOL u32 ISTDFIORead(ISTDFIOFile*, void*, u32, u32*) __attribute__((never_inline))
77 {
78     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
79 }
ISTDFIOWrite(ISTDFIOFile *,void *,u32)80 SDK_WEAK_SYMBOL u32 ISTDFIOWrite(ISTDFIOFile*, void*, u32) __attribute__((never_inline))
81 {
82     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
83 }
ISTDFIOSeek(ISTDFIOFile *,s32,u32,u32 *)84 SDK_WEAK_SYMBOL u32 ISTDFIOSeek(ISTDFIOFile*, s32, u32, u32*) __attribute__((never_inline))
85 {
86     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
87 }
ISTDFIOLength(ISTDFIOFile *,u32 *)88 SDK_WEAK_SYMBOL u32 ISTDFIOLength(ISTDFIOFile*, u32*) __attribute__((never_inline))
89 {
90     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
91 }
ISTDFIOFindFirst(ISTDFIOFile *,ISTDFIOFindData *,const char *)92 SDK_WEAK_SYMBOL u32 ISTDFIOFindFirst(ISTDFIOFile*, ISTDFIOFindData*, const char*) __attribute__((never_inline))
93 {
94     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
95 }
ISTDFIOFindNext(ISTDFIOFile *,ISTDFIOFindData *)96 SDK_WEAK_SYMBOL u32 ISTDFIOFindNext(ISTDFIOFile*, ISTDFIOFindData*) __attribute__((never_inline))
97 {
98     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
99 }
ISTDFIOFindClose(ISTDFIOFile *)100 SDK_WEAK_SYMBOL u32 ISTDFIOFindClose(ISTDFIOFile*) __attribute__((never_inline))
101 {
102     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
103 }
ISTDFIORemove(const char *)104 SDK_WEAK_SYMBOL u32 ISTDFIORemove(const char*) __attribute__((never_inline))
105 {
106     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
107 }
ISTDFIORename(const char *,const char *)108 SDK_WEAK_SYMBOL u32 ISTDFIORename(const char*, const char*) __attribute__((never_inline))
109 {
110     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
111 }
ISTDFIOMkDir(const char *)112 SDK_WEAK_SYMBOL u32 ISTDFIOMkDir(const char*) __attribute__((never_inline))
113 {
114     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
115 }
ISTDFIOGetAttribute(const char *,CFIOAtrb *)116 SDK_WEAK_SYMBOL u32 ISTDFIOGetAttribute(const char*, CFIOAtrb*) __attribute__((never_inline))
117 {
118     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
119 }
ISTDFIORmDir(const char *)120 SDK_WEAK_SYMBOL u32 ISTDFIORmDir(const char*) __attribute__((never_inline))
121 {
122     return ISTDFIO_FILEIO_ERROR_NOTCONNECT;
123 }
124 
125 
126 /*---------------------------------------------------------------------------*
127   Name:         DEMOi_HIO_AllocFile
128 
129   Description:  Allocates an HIO file structure
130 
131   Arguments:    context: DEMOHIOContext
132 
133   Returns:      A file structure or NULL
134  *---------------------------------------------------------------------------*/
DEMOi_HIO_AllocFile(DEMOHIOContext * context)135 static ISTDFIOFile* DEMOi_HIO_AllocFile(DEMOHIOContext *context)
136 {
137     ISTDFIOFile    *file = NULL;
138     u32     index = MATH_CTZ((u32)~context->busyfiles);
139     if (index < DEMO_HIO_HANDLE_MAX)
140     {
141         context->busyfiles |= (1 << index);
142         file = &context->file[index];
143     }
144     return file;
145 }
146 
147 /*---------------------------------------------------------------------------*
148   Name:         DEMOi_HIO_AllocFile
149 
150   Description:  Releases an HIO file structure
151 
152   Arguments:    context: DEMOHIOContext
153                 file: File structure
154 
155   Returns:      None
156  *---------------------------------------------------------------------------*/
DEMOi_HIO_FreeFile(DEMOHIOContext * context,ISTDFIOFile * file)157 static void DEMOi_HIO_FreeFile(DEMOHIOContext *context, ISTDFIOFile *file)
158 {
159     int     index = (context->file - file);
160     context->busyfiles &= ~(1 << index);
161     context->validfiles &= ~(1 << index);
162 }
163 
164 /*---------------------------------------------------------------------------*
165   Name:         DEMOi_HIO_CreateFullPath
166 
167   Description:  Converts an FS path name into a full HIO path name
168 
169   Arguments:    context: DEMOHIOContext
170                 dst: Location to store the full path
171                 relpath: Relative path from the root
172 
173   Returns:      The processing result for the command
174  *---------------------------------------------------------------------------*/
DEMOi_HIO_CreateFullPath(DEMOHIOContext * context,char * dst,const char * relpath)175 static void DEMOi_HIO_CreateFullPath(DEMOHIOContext *context, char *dst, const char *relpath)
176 {
177     // If ":" is included in the path name, use it unchanged
178     if (STD_SearchString(relpath, ":") != NULL)
179     {
180         (void)STD_TSPrintf(dst, "%s", relpath);
181     }
182     // Otherwise, connect the relative path with the root directory
183     else
184     {
185         (void)STD_TSPrintf(dst, "%s/%s", context->basepath, relpath);
186     }
187     // Remove trailing forward slashes ('/')
188     {
189         int    length = STD_GetStringLength(dst);
190         if ((--length >= 0) && ((dst[length] == '\\') || (dst[length] == '/')))
191         {
192             dst[length] = '\0';
193         }
194     }
195 }
196 
197 /*---------------------------------------------------------------------------*
198   Name:         DEMOi_HIO_ConvertError
199 
200   Description:  Converts an HIO error code into an FSResult
201 
202   Arguments:    error: Error code
203 
204   Returns:      The error code converted into an FSResult
205  *---------------------------------------------------------------------------*/
DEMOi_HIO_ConvertError(u32 error)206 static FSResult DEMOi_HIO_ConvertError(u32 error)
207 {
208     if (error == ISTDFIO_FILEIO_ERROR_SUCCESS)
209     {
210         return FS_RESULT_SUCCESS;
211     }
212     else if (error == ISTDFIO_FILEIO_ERROR_COMERROR)
213     {
214         return FS_RESULT_ERROR;
215     }
216     else if (error == ISTDFIO_FILEIO_ERROR_NOTCONNECT)
217     {
218         return FS_RESULT_ERROR;
219     }
220     else if (error == ISTDFIO_FILEIO_ERROR_SERVERERROR)
221     {
222         return FS_RESULT_ERROR;
223     }
224     else if (error == ISTDFIO_FILEIO_ERROR_NOMOREFILES)
225     {
226         return FS_RESULT_FAILURE;
227     }
228     else if (error == ISTDFIO_FILEIO_ERROR_FILENOTFOUND)
229     {
230         return FS_RESULT_ERROR;
231     }
232     else if (error == ISTDFIO_FILEIO_ERROR_PATHTOOLONG)
233     {
234         return FS_RESULT_INVALID_PARAMETER;
235     }
236     else
237     {
238         return FS_RESULT_ERROR;
239     }
240 }
241 
242 /*---------------------------------------------------------------------------*
243   Name:         DEMOi_HIO_ConvertTime
244 
245   Description:  Converts an HIO date-time structure into an FSDateTime
246 
247   Arguments:    dst: The FSDateTime to convert to
248                 src: The original CFIODateTime to convert
249 
250   Returns:      None
251  *---------------------------------------------------------------------------*/
DEMOi_HIO_ConvertTime(FSDateTime * dst,const CFIODateTime * src)252 static void DEMOi_HIO_ConvertTime(FSDateTime *dst, const CFIODateTime *src)
253 {
254     dst->year = src->m_nYear;
255     dst->month = src->m_nMonth;
256     dst->day = src->m_nDay;
257     dst->hour = src->m_nHour;
258     dst->minute = src->m_nMinute;
259     dst->second = src->m_nSecond;
260 }
261 
262 /*---------------------------------------------------------------------------*
263  * The following is the FS command interface
264  *---------------------------------------------------------------------------*/
265 
266 /*---------------------------------------------------------------------------*
267   Name:         DEMOi_HIO_GetArchiveCaps
268 
269   Description:  The FS_COMMAND_GETARCHIVECAPS command.
270 
271   Arguments:    arc: The calling archive
272                 caps: Location to save the device capability flag
273 
274   Returns:      The processing result for the command
275  *---------------------------------------------------------------------------*/
DEMOi_HIO_GetArchiveCaps(FSArchive * arc,u32 * caps)276 static FSResult DEMOi_HIO_GetArchiveCaps(FSArchive *arc, u32 *caps)
277 {
278     (void)arc;
279     *caps = 0;
280     return FS_RESULT_SUCCESS;
281 }
282 
283 /*---------------------------------------------------------------------------*
284   Name:         DEMOi_HIO_GetPathInfo
285 
286   Description:  The FS_COMMAND_GETPATHINFO command
287 
288   Arguments:    arc: The calling archive
289                 baseid: The base directory ID (0 for the root)
290                 relpath: The path
291                 info: Location to save file information
292 
293   Returns:      The processing result for the command
294  *---------------------------------------------------------------------------*/
DEMOi_HIO_GetPathInfo(FSArchive * arc,u32 baseid,const char * relpath,FSPathInfo * info)295 static FSResult DEMOi_HIO_GetPathInfo(FSArchive *arc, u32 baseid, const char *relpath, FSPathInfo *info)
296 {
297     FSResult        result = FS_RESULT_ERROR;
298     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
299     char           *tmppath = context->fullpath[0];
300     CFIOAtrb        stat[1];
301     (void)baseid;
302     DEMOi_HIO_CreateFullPath(context, tmppath, relpath);
303     result = DEMOi_HIO_ConvertError(ISTDFIOGetAttribute(tmppath, stat));
304     if (result == FS_RESULT_ERROR)
305     {
306         info->attributes = (stat->m_nAtrb & FS_ATTRIBUTE_DOS_MASK);
307         if ((stat->m_nAtrb & ISTDFIO_FILEIO_ATTRIBUTE_DIRECTORY) != 0)
308         {
309             info->attributes |= FS_ATTRIBUTE_IS_DIRECTORY;
310         }
311 //        info->filesize = stat->m_nSize;
312         DEMOi_HIO_ConvertTime(&info->atime, &stat->m_atime);
313         DEMOi_HIO_ConvertTime(&info->mtime, &stat->m_mtime);
314         DEMOi_HIO_ConvertTime(&info->ctime, &stat->m_ctime);
315         info->id = FS_INVALID_FILE_ID;
316     }
317     return result;
318 }
319 
320 /*---------------------------------------------------------------------------*
321   Name:         DEMOi_HIO_CreateFile
322 
323   Description:  The FS_COMMAND_CREATE_FILE command
324 
325   Arguments:
326 
327   Returns:      The processing result for the command
328  *---------------------------------------------------------------------------*/
DEMOi_HIO_CreateFile(FSArchive * arc,u32 baseid,const char * relpath,u32 permit)329 static FSResult DEMOi_HIO_CreateFile(FSArchive *arc, u32 baseid, const char *relpath, u32 permit)
330 {
331     FSResult        result = FS_RESULT_ERROR;
332     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
333     char           *tmppath = context->fullpath[0];
334     // Files are created in the process of opening them
335     ISTDFIOFile    *file = DEMOi_HIO_AllocFile(context);
336     (void)baseid;
337     if (!file)
338     {
339         result = FS_RESULT_NO_MORE_RESOURCE;
340     }
341     else
342     {
343         u32     flags = 0;
344         flags |= ((permit & FS_PERMIT_R) != 0) ? ISTDFIO_FILEIO_FLAG_READ : 0;
345         flags |= ((permit & FS_PERMIT_W) != 0) ? ISTDFIO_FILEIO_FLAG_WRITE : 0;
346         flags |= ISTDFIO_FILEIO_FLAG_FORCE;
347         DEMOi_HIO_CreateFullPath(context, tmppath, relpath);
348         result = DEMOi_HIO_ConvertError(ISTDFIOOpen(file, tmppath, flags));
349         if (result == FS_RESULT_SUCCESS)
350         {
351             (void)ISTDFIOClose(file);
352         }
353         DEMOi_HIO_FreeFile(context, file);
354     }
355     return result;
356 }
357 
358 /*---------------------------------------------------------------------------*
359   Name:         DEMOi_HIO_DeleteFile
360 
361   Description:  The FS_COMMAND_DELETE_FILE command
362 
363   Arguments:
364 
365   Returns:      The processing result for the command
366  *---------------------------------------------------------------------------*/
DEMOi_HIO_DeleteFile(FSArchive * arc,u32 baseid,const char * relpath)367 static FSResult DEMOi_HIO_DeleteFile(FSArchive *arc, u32 baseid, const char *relpath)
368 {
369     FSResult        result = FS_RESULT_ERROR;
370     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
371     char           *tmppath = context->fullpath[0];
372     (void)baseid;
373     DEMOi_HIO_CreateFullPath(context, tmppath, relpath);
374     result = DEMOi_HIO_ConvertError(ISTDFIORemove(tmppath));
375     return result;
376 }
377 
378 /*---------------------------------------------------------------------------*
379   Name:         DEMOi_HIO_RenameFileOrDirectory
380 
381   Description:  The FS_COMMAND_RENAME_FILE or FS_COMMAND_RENAME_DIRECTORY command
382 
383   Arguments:
384 
385   Returns:      The processing result for the command
386  *---------------------------------------------------------------------------*/
DEMOi_HIO_RenameFileOrDirectory(FSArchive * arc,u32 baseid_src,const char * relpath_src,u32 baseid_dst,const char * relpath_dst)387 static FSResult DEMOi_HIO_RenameFileOrDirectory(FSArchive *arc,
388                                               u32 baseid_src, const char *relpath_src,
389                                               u32 baseid_dst, const char *relpath_dst)
390 {
391     FSResult        result = FS_RESULT_ERROR;
392     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
393     char           *tmppath1 = context->fullpath[0];
394     char           *tmppath2 = context->fullpath[1];
395     (void)baseid_src;
396     (void)baseid_dst;
397     DEMOi_HIO_CreateFullPath(context, tmppath1, relpath_src);
398     DEMOi_HIO_CreateFullPath(context, tmppath2, relpath_dst);
399     result = DEMOi_HIO_ConvertError(ISTDFIORename(tmppath1, tmppath2));
400     return result;
401 }
402 
403 /*---------------------------------------------------------------------------*
404   Name:         DEMOi_HIO_CreateDirectory
405 
406   Description:  The FS_COMMAND_CREATE_DIRECTORY command
407 
408   Arguments:
409 
410   Returns:      The processing result for the command
411  *---------------------------------------------------------------------------*/
DEMOi_HIO_CreateDirectory(FSArchive * arc,u32 baseid,const char * relpath,u32 permit)412 static FSResult DEMOi_HIO_CreateDirectory(FSArchive *arc, u32 baseid, const char *relpath, u32 permit)
413 {
414     FSResult        result = FS_RESULT_ERROR;
415     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
416     char           *tmppath = context->fullpath[0];
417     (void)baseid;
418     (void)permit;
419     DEMOi_HIO_CreateFullPath(context, tmppath, relpath);
420     result = DEMOi_HIO_ConvertError(ISTDFIOMkDir(tmppath));
421     return result;
422 }
423 
424 /*---------------------------------------------------------------------------*
425   Name:         DEMOi_HIO_DeleteDirectory
426 
427   Description:  The FS_COMMAND_DELETE_DIRECTORY command
428 
429   Arguments:
430 
431   Returns:      The processing result for the command
432  *---------------------------------------------------------------------------*/
DEMOi_HIO_DeleteDirectory(FSArchive * arc,u32 baseid,const char * relpath)433 static FSResult DEMOi_HIO_DeleteDirectory(FSArchive *arc, u32 baseid, const char *relpath)
434 {
435     FSResult        result = FS_RESULT_ERROR;
436     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
437     char           *tmppath = context->fullpath[0];
438     (void)baseid;
439     DEMOi_HIO_CreateFullPath(context, tmppath, relpath);
440     result = DEMOi_HIO_ConvertError(ISTDFIORmDir(tmppath));
441     return result;
442 }
443 
444 /*---------------------------------------------------------------------------*
445   Name:         DEMOi_HIO_OpenFile
446 
447   Description:  The FS_COMMAND_OPENFILE command
448 
449   Arguments:    arc: The calling archive
450                 file: The target file
451                 baseid: The base directory (0 for the root)
452                 path :   File path
453                 mode: The access mode
454 
455   Returns:      The processing result for the command
456  *---------------------------------------------------------------------------*/
DEMOi_HIO_OpenFile(FSArchive * arc,FSFile * file,u32 baseid,const char * path,u32 mode)457 static FSResult DEMOi_HIO_OpenFile(FSArchive *arc, FSFile *file, u32 baseid, const char *path, u32 mode)
458 {
459     FSResult        result = FS_RESULT_ERROR;
460     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
461     char           *tmppath = context->fullpath[0];
462     ISTDFIOFile    *handle = DEMOi_HIO_AllocFile(context);
463     (void)baseid;
464     if (!handle)
465     {
466         result = FS_RESULT_NO_MORE_RESOURCE;
467     }
468     else
469     {
470         u32     flags = 0;
471         flags |= ((mode & FS_FILEMODE_R) != 0) ? ISTDFIO_FILEIO_FLAG_READ : 0;
472         flags |= ((mode & FS_FILEMODE_W) != 0) ? ISTDFIO_FILEIO_FLAG_WRITE : 0;
473         DEMOi_HIO_CreateFullPath(context, tmppath, path);
474         result = DEMOi_HIO_ConvertError(ISTDFIOOpen(handle, tmppath, flags));
475         if (result == FS_RESULT_SUCCESS)
476         {
477             FS_SetFileHandle(file, arc, (void *)handle);
478         }
479     }
480     return result;
481 }
482 
483 /*---------------------------------------------------------------------------*
484   Name:         DEMOi_HIO_CloseFile
485 
486   Description:  The FS_COMMAND_CLOSEFILE command
487 
488   Arguments:    arc: The calling archive
489                 file: The target file
490 
491   Returns:      The processing result for the command
492  *---------------------------------------------------------------------------*/
DEMOi_HIO_CloseFile(FSArchive * arc,FSFile * file)493 static FSResult DEMOi_HIO_CloseFile(FSArchive *arc, FSFile *file)
494 {
495     FSResult        result = FS_RESULT_ERROR;
496     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
497     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
498     result = DEMOi_HIO_ConvertError(ISTDFIOClose(handle));
499     DEMOi_HIO_FreeFile(context, handle);
500     FS_DetachHandle(file);
501     return result;
502 }
503 
504 /*---------------------------------------------------------------------------*
505   Name:         DEMOi_HIO_ReadFile
506 
507   Description:  The FS_COMMAND_READFILE command
508 
509   Arguments:    arc: The calling archive
510                 file: The target file
511                 buffer: The memory to transfer to
512                 length: Transfer size
513 
514   Returns:      The processing result for the command
515  *---------------------------------------------------------------------------*/
DEMOi_HIO_ReadFile(FSArchive * arc,FSFile * file,void * buffer,u32 * length)516 static FSResult DEMOi_HIO_ReadFile(FSArchive *arc, FSFile *file, void *buffer, u32 *length)
517 {
518     FSResult        result = FS_RESULT_ERROR;
519     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
520     (void)arc;
521     result = DEMOi_HIO_ConvertError(ISTDFIORead(handle, buffer, *length, length));
522     return result;
523 }
524 
525 /*---------------------------------------------------------------------------*
526   Name:         DEMOi_HIO_WriteFile
527 
528   Description:  The FS_COMMAND_WRITEFILE command
529 
530   Arguments:    arc: The calling archive
531                 file: The target file
532                 buffer: The memory to transfer from
533                 length: Transfer size
534 
535   Returns:      The processing result for the command
536  *---------------------------------------------------------------------------*/
DEMOi_HIO_WriteFile(FSArchive * arc,FSFile * file,const void * buffer,u32 * length)537 static FSResult DEMOi_HIO_WriteFile(FSArchive *arc, FSFile *file, const void *buffer, u32 *length)
538 {
539     FSResult        result = FS_RESULT_ERROR;
540     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
541     (void)arc;
542     result = DEMOi_HIO_ConvertError(ISTDFIOWrite(handle, (void *)buffer, *length));
543     return result;
544 }
545 
546 /*---------------------------------------------------------------------------*
547   Name:         DEMOi_HIO_SeekFile
548 
549   Description:  The FS_COMMAND_SEEKFILE command
550 
551   Arguments:    arc: The calling archive
552                 file: The target file
553                 offset: The displacement and moved-to position
554                 from: The starting point to seek from
555 
556   Returns:      The processing result for the command
557  *---------------------------------------------------------------------------*/
DEMOi_HIO_SeekFile(FSArchive * arc,FSFile * file,int * offset,FSSeekFileMode from)558 static FSResult DEMOi_HIO_SeekFile(FSArchive *arc, FSFile *file, int *offset, FSSeekFileMode from)
559 {
560     FSResult        result = FS_RESULT_ERROR;
561     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
562     u32             mode = ISTDFIO_FILEIO_SEEK_CURRENT;
563     (void)arc;
564     if (from == FS_SEEK_SET)
565     {
566         mode = ISTDFIO_FILEIO_SEEK_BEGIN;
567     }
568     else if (from == FS_SEEK_CUR)
569     {
570         mode = ISTDFIO_FILEIO_SEEK_CURRENT;
571     }
572     else if (from == FS_SEEK_END)
573     {
574         mode = ISTDFIO_FILEIO_SEEK_END;
575     }
576     result = DEMOi_HIO_ConvertError(ISTDFIOSeek(handle, (s32)*offset, mode, (u32*)offset));
577     return result;
578 }
579 
580 /*---------------------------------------------------------------------------*
581   Name:         DEMOi_HIO_GetFileLength
582 
583   Description:  The FS_COMMAND_GETFILELENGTH command
584 
585   Arguments:    arc: The calling archive
586                 file: The target file
587                 length: Location to save the obtained size
588 
589   Returns:      The processing result for the command
590  *---------------------------------------------------------------------------*/
DEMOi_HIO_GetFileLength(FSArchive * arc,FSFile * file,u32 * length)591 static FSResult DEMOi_HIO_GetFileLength(FSArchive *arc, FSFile *file, u32 *length)
592 {
593     FSResult        result = FS_RESULT_ERROR;
594     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
595     (void)arc;
596     result = DEMOi_HIO_ConvertError(ISTDFIOLength(handle, length));
597     return result;
598 }
599 
600 /*---------------------------------------------------------------------------*
601   Name:         DEMOi_HIO_GetFilePosition
602 
603   Description:  The FS_COMMAND_GETFILEPOSITION command
604 
605   Arguments:    arc: The calling archive
606                 file: The target file
607                 position: Location to store the obtained position
608 
609   Returns:      The processing result for the command
610  *---------------------------------------------------------------------------*/
DEMOi_HIO_GetFilePosition(FSArchive * arc,FSFile * file,u32 * position)611 static FSResult DEMOi_HIO_GetFilePosition(FSArchive *arc, FSFile *file, u32 *position)
612 {
613     *position = 0;
614     return DEMOi_HIO_SeekFile(arc, file, (int *)position, FS_SEEK_CUR);
615 }
616 
617 /*---------------------------------------------------------------------------*
618   Name:         DEMOi_HIO_OpenDirectory
619 
620   Description:  The FS_COMMAND_OPENDIRECTORY command
621 
622   Arguments:    arc: The calling archive
623                 file: The target file
624                 baseid: The base directory ID (0 for the root)
625                 path: The path
626                 mode: The access mode
627 
628   Returns:      The processing result for the command
629  *---------------------------------------------------------------------------*/
DEMOi_HIO_OpenDirectory(FSArchive * arc,FSFile * file,u32 baseid,const char * path,u32 mode)630 static FSResult DEMOi_HIO_OpenDirectory(FSArchive *arc, FSFile *file, u32 baseid,
631                                       const char *path, u32 mode)
632 {
633     FSResult        result = FS_RESULT_ERROR;
634     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
635     char           *tmppath = context->fullpath[0];
636     ISTDFIOFile    *handle = DEMOi_HIO_AllocFile(context);
637     (void)baseid;
638     if (!handle)
639     {
640         result = FS_RESULT_NO_MORE_RESOURCE;
641     }
642     else
643     {
644         int                 index = handle - context->file;
645         ISTDFIOFindData    *data = &context->ffdata[index];
646         u32     flags = 0;
647         flags |= ((mode & FS_FILEMODE_R) != 0) ? ISTDFIO_FILEIO_FLAG_READ : 0;
648         flags |= ((mode & FS_FILEMODE_W) != 0) ? ISTDFIO_FILEIO_FLAG_WRITE : 0;
649         DEMOi_HIO_CreateFullPath(context, tmppath, path);
650         // Disable special wildcard specifications
651         if (*tmppath)
652         {
653             char  *s = tmppath + STD_GetStringLength(tmppath);
654             while (*--s == '*')
655             {
656             }
657             if (*s != '/')
658             {
659                 *++s = '/';
660             }
661             *++s = '*';
662             *++s = '\0';
663         }
664         result = DEMOi_HIO_ConvertError(ISTDFIOFindFirst(handle, data, tmppath));
665         if (result == FS_RESULT_SUCCESS)
666         {
667             context->validfiles |= (1 << index);
668             FS_SetDirectoryHandle(file, arc, (void *)handle);
669         }
670     }
671     return result;
672 }
673 
674 /*---------------------------------------------------------------------------*
675   Name:         DEMOi_HIO_CloseDirectory
676 
677   Description:  The FS_COMMAND_CLOSEDIRECTORY command
678 
679   Arguments:    arc: The calling archive
680                 file: The target file
681 
682   Returns:      The processing result for the command
683  *---------------------------------------------------------------------------*/
DEMOi_HIO_CloseDirectory(FSArchive * arc,FSFile * file)684 static FSResult DEMOi_HIO_CloseDirectory(FSArchive *arc, FSFile *file)
685 {
686     FSResult        result = FS_RESULT_ERROR;
687     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
688     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
689     result = DEMOi_HIO_ConvertError(ISTDFIOFindClose(handle));
690     DEMOi_HIO_FreeFile(context, handle);
691     FS_DetachHandle(file);
692     return result;
693 }
694 
695 /*---------------------------------------------------------------------------*
696   Name:         DEMOi_HIO_ReadDirectory
697 
698   Description:  The FS_COMMAND_READDIR command
699 
700   Arguments:    arc: The calling archive
701                 file: The target file
702                 info: Location to save information
703 
704   Returns:      The processing result for the command
705  *---------------------------------------------------------------------------*/
DEMOi_HIO_ReadDirectory(FSArchive * arc,FSFile * file,FSDirectoryEntryInfo * info)706 static FSResult DEMOi_HIO_ReadDirectory(FSArchive * arc, FSFile * file,
707                                         FSDirectoryEntryInfo * info)
708 {
709     FSResult        result = FS_RESULT_ERROR;
710     DEMOHIOContext   *context = (DEMOHIOContext *)FS_GetArchiveUserData(arc);
711     ISTDFIOFile    *handle = (ISTDFIOFile *)FS_GetFileUserData(file);
712     int             index = handle - context->file;
713     if ((context->validfiles & (1 << index)) == 0)
714     {
715         result = FS_RESULT_FAILURE;
716     }
717     else
718     {
719         ISTDFIOFindData    *data = &context->ffdata[index];
720         info->shortname_length = 0;
721         info->shortname[0] = 0;
722         info->longname_length = (u32)STD_GetStringLength(data->m_bufName);
723         (void)STD_CopyLString(info->longname, data->m_bufName, sizeof(info->longname));
724         info->attributes = (data->m_nAttrib & FS_ATTRIBUTE_DOS_MASK);
725         if ((data->m_nAttrib & ISTDFIO_FILEIO_ATTRIBUTE_DIRECTORY) != 0)
726         {
727             info->attributes |= FS_ATTRIBUTE_IS_DIRECTORY;
728         }
729         info->filesize = data->m_nSize;
730 //        DEMOi_HIO_ConvertTime(&info->atime, data->m_atime);
731 //        DEMOi_HIO_ConvertTime(&info->mtime, data->m_mtime);
732 //        DEMOi_HIO_ConvertTime(&info->ctime, data->m_ctime);
733         result = FS_RESULT_SUCCESS;
734         if (ISTDFIOFindNext(handle, data) != ISTDFIO_FILEIO_ERROR_SUCCESS)
735         {
736             context->validfiles &= ~(1 << index);
737         }
738     }
739     return result;
740 }
741 
742 #endif // SDK_LINK_ISTD
743 
744 
745 
746 /*---------------------------------------------------------------------------*
747   Name:         DEMOMountHostIO
748 
749   Description:  Mounts the IS-TWL-DEBUGGER Host I/O file system as "hostio:" on the FS
750 
751 
752   Arguments:    basepath: Root directory on the standard debug host side.
753                             Specifying "hostio:/relpath" as an FS path implies "basepath/relpath" on the host side.
754 
755 
756   Returns:      None
757  *---------------------------------------------------------------------------*/
DEMOMountHostIO(const char * basepath)758 void DEMOMountHostIO(const char *basepath)
759 {
760 
761 #ifndef SDK_LINK_ISTD
762 
763     // You cannot access Host I/O access API definitions if the IS-TWL-DEBUGGER software is not installed in the compilation environment
764     //
765     (void)basepath;
766     OS_TWarning("cannot use HostI/O on this compile-time environment.\n");
767 
768 #else // SDK_LINK_ISTD
769 
770     // You cannot actually use Host I/O features if the IS-TWL-DEBUGGER software is not the runtime environment
771     //
772     if ((OS_GetConsoleType() & OS_CONSOLE_TWLDEBUGGER) == 0)
773     {
774         OS_TWarning("cannot use HostI/O on this run-time environment.\n");
775     }
776 
777     // You cannot use Host I/O if the IS-TWL-DEBUGGER software is not installed in the linking environment, even if IS-TWL-DEBUGGER is the runtime environment
778     //
779     else if (ISTDHIOInit(), !ISTDHIOOpen(ISTDHIODEVMASK_AUTOSELECT))
780     {
781         OS_TWarning("failed to open HostI/O device.\n");
782     }
783 
784     // Host I/O can only be used when IS-TWL-DEBUGGER is the runtime environment and the IS-TWL-DEBUGGER library is present in both the compilation and linking environments
785     //
786     else
787     {
788         static const FSArchiveInterface FSiArchiveHIOInterface =
789         {
790             // Commands that are compatible with old specifications
791             DEMOi_HIO_ReadFile,
792             DEMOi_HIO_WriteFile,
793             NULL,               // SeekDirectory
794             DEMOi_HIO_ReadDirectory,
795             NULL,               // FindPath
796             NULL,               // GetPath
797             NULL,               // OpenFileFast
798             NULL,               // OpenFileDirect
799             DEMOi_HIO_CloseFile,
800             NULL,               // Activate
801             NULL,               // Idle
802             NULL,               // Suspend
803             NULL,               // Resume
804             // Items that are compatible with old specifications but were not commands
805             DEMOi_HIO_OpenFile,
806             DEMOi_HIO_SeekFile,
807             DEMOi_HIO_GetFileLength,
808             DEMOi_HIO_GetFilePosition,
809             // Extended commands in the new specifications
810             NULL,               // Mount
811             NULL,               // Unmount
812             DEMOi_HIO_GetArchiveCaps,
813             DEMOi_HIO_CreateFile,
814             DEMOi_HIO_DeleteFile,
815             DEMOi_HIO_RenameFileOrDirectory,
816             DEMOi_HIO_GetPathInfo,
817             NULL,               // SetFileInfo
818             DEMOi_HIO_CreateDirectory,
819             DEMOi_HIO_DeleteDirectory,
820             DEMOi_HIO_RenameFileOrDirectory,
821             NULL,               // GetArchiveResource
822             NULL,               // 29UL
823             NULL,               // FlushFile
824             NULL,               // SetFileLength
825             DEMOi_HIO_OpenDirectory,
826             DEMOi_HIO_CloseDirectory,
827         };
828         DEMOiHIODrive->busyfiles = 0;
829         DEMOiHIODrive->validfiles = 0;
830         (void)STD_CopyString(DEMOiHIODrive->basepath, basepath);
831         if (FS_RegisterArchiveName(DEMOiHIODrive->arc, "hostio", 6))
832         {
833             (void)FS_MountArchive(DEMOiHIODrive->arc, DEMOiHIODrive, &FSiArchiveHIOInterface, 0);
834         }
835     }
836 
837 #endif // SDK_LINK_ISTD
838 }
839