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