1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Daniel Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
27 #include <sys/param.h>
28 #include <sys/mount.h>
29 #elif defined(__APPLE__)
30 #include <sys/param.h>
31 #include <sys/mount.h>
44 #include "dir-win32.h"
54 /* Windows (and potentially other OSes) distinguish binary and text files.
55 * Define a dummy for the others. */
60 /* Unicode compatibility for win32 */
61 #if defined __MINGW32__
62 /* Rockbox unicode functions */
63 extern const unsigned char* utf8decode(const unsigned char *utf8
,
65 extern unsigned char* utf8encode(unsigned long ucs
, unsigned char *utf8
);
67 /* Static buffers for the conversion results. This isn't thread safe,
68 * but it's sufficient for rockbox. */
69 static unsigned char convbuf1
[3*MAX_PATH
];
70 static unsigned char convbuf2
[3*MAX_PATH
];
72 static wchar_t* utf8_to_ucs2(const unsigned char *utf8
, void *buffer
)
74 wchar_t *ucs
= buffer
;
77 utf8
= utf8decode(utf8
, ucs
++);
82 static unsigned char *ucs2_to_utf8(const wchar_t *ucs
, unsigned char *buffer
)
84 unsigned char *utf8
= buffer
;
87 utf8
= utf8encode(*ucs
++, utf8
);
93 #define UTF8_TO_OS(a) utf8_to_ucs2(a,convbuf1)
94 #define OS_TO_UTF8(a) ucs2_to_utf8(a,convbuf1)
96 #define DIRENT_T struct _wdirent
97 #define STAT_T struct _stat
98 extern int _wmkdir(const wchar_t*);
99 extern int _wrmdir(const wchar_t*);
100 #define MKDIR(a,b) (_wmkdir)(UTF8_TO_OS(a))
101 #define RMDIR(a) (_wrmdir)(UTF8_TO_OS(a))
102 #define OPENDIR(a) (_wopendir)(UTF8_TO_OS(a))
103 #define READDIR(a) (_wreaddir)(a)
104 #define CLOSEDIR(a) (_wclosedir)(a)
105 #define STAT(a,b) (_wstat)(UTF8_TO_OS(a),b)
106 #define OPEN(a,b,c) (_wopen)(UTF8_TO_OS(a),b,c)
107 #define REMOVE(a) (_wremove)(UTF8_TO_OS(a))
108 #define RENAME(a,b) (_wrename)(UTF8_TO_OS(a),utf8_to_ucs2(b,convbuf2))
110 #else /* !__MINGW32__ */
112 #define UTF8_TO_OS(a) (a)
113 #define OS_TO_UTF8(a) (a)
115 #define DIRENT_T struct dirent
116 #define STAT_T struct stat
117 #define MKDIR(a,b) (mkdir)(a,b)
118 #define RMDIR(a) (rmdir)(a)
119 #define OPENDIR(a) (opendir)(a)
120 #define READDIR(a) (readdir)(a)
121 #define CLOSEDIR(a) (closedir)(a)
122 #define STAT(a,b) (stat)(a,b)
123 #define OPEN(a,b,c) (open)(a,b,c)
124 #define REMOVE(a) (remove)(a)
125 #define RENAME(a,b) (rename)(a,b)
127 #endif /* !__MINGW32__ */
131 void dircache_remove(const char *name
);
132 void dircache_rename(const char *oldpath
, const char *newpath
);
135 #define SIMULATOR_ARCHOS_ROOT "archos"
138 unsigned char d_name
[MAX_PATH
];
142 unsigned short wrtdate
; /* Last write date */
143 unsigned short wrttime
; /* Last write time */
147 void *dir
; /* actually a DIR* dir */
156 typedef struct mydir MYDIR
;
158 #if 1 /* maybe this needs disabling for MSVC... */
159 static unsigned int rockbox2sim(int opt
)
161 int newopt
= O_BINARY
;
178 MYDIR
*sim_opendir(const char *name
)
180 char buffer
[MAX_PATH
]; /* sufficiently big */
186 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
187 dir
=(DIR_T
*)OPENDIR(buffer
);
191 dir
=(DIR_T
*)OPENDIR(name
);
194 MYDIR
*my
= (MYDIR
*)malloc(sizeof(MYDIR
));
196 my
->name
= (char *)strdup(name
);
200 /* failed open, return NULL */
204 struct sim_dirent
*sim_readdir(MYDIR
*dir
)
206 char buffer
[512]; /* sufficiently big */
207 static struct sim_dirent secret
;
209 DIRENT_T
*x11
= READDIR(dir
->dir
);
213 return (struct sim_dirent
*)0;
215 strcpy((char *)secret
.d_name
, OS_TO_UTF8(x11
->d_name
));
217 /* build file name */
219 snprintf(buffer
, sizeof(buffer
), "%s/%s", dir
->name
, secret
.d_name
);
221 snprintf(buffer
, sizeof(buffer
), SIMULATOR_ARCHOS_ROOT
"%s/%s",
222 dir
->name
, secret
.d_name
);
224 STAT(buffer
, &s
); /* get info */
226 #define ATTR_DIRECTORY 0x10
228 secret
.attribute
= S_ISDIR(s
.st_mode
)?ATTR_DIRECTORY
:0;
229 secret
.size
= s
.st_size
;
231 tm
= localtime(&(s
.st_mtime
));
232 secret
.wrtdate
= ((tm
->tm_year
- 80) << 9) |
233 ((tm
->tm_mon
+ 1) << 5) |
235 secret
.wrttime
= (tm
->tm_hour
<< 11) |
241 void sim_closedir(MYDIR
*dir
)
249 int sim_open(const char *name
, int o
)
251 char buffer
[MAX_PATH
]; /* sufficiently big */
252 int opts
= rockbox2sim(o
);
257 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
259 debugf("We open the real file '%s'\n", buffer
);
260 return OPEN(buffer
, opts
, 0666);
263 fprintf(stderr
, "WARNING, bad file name lacks slash: %s\n",
267 return OPEN(name
, opts
, 0666);
272 int sim_creat(const char *name
)
275 char buffer
[MAX_PATH
]; /* sufficiently big */
278 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
280 debugf("We create the real file '%s'\n", buffer
);
281 return OPEN(buffer
, O_BINARY
| O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
283 fprintf(stderr
, "WARNING, bad file name lacks slash: %s\n", name
);
286 return OPEN(name
, O_BINARY
| O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
290 int sim_mkdir(const char *name
)
293 return MKDIR(name
, 0777);
295 char buffer
[MAX_PATH
]; /* sufficiently big */
297 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
299 debugf("We create the real directory '%s'\n", buffer
);
300 return MKDIR(buffer
, 0777);
304 int sim_rmdir(const char *name
)
309 char buffer
[MAX_PATH
]; /* sufficiently big */
312 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
314 debugf("We remove the real directory '%s'\n", buffer
);
315 return RMDIR(buffer
);
321 int sim_remove(const char *name
)
326 char buffer
[MAX_PATH
]; /* sufficiently big */
329 dircache_remove(name
);
333 snprintf(buffer
, sizeof(buffer
), "%s%s", SIMULATOR_ARCHOS_ROOT
, name
);
335 debugf("We remove the real file '%s'\n", buffer
);
336 return REMOVE(buffer
);
342 int sim_rename(const char *oldpath
, const char* newpath
)
345 return RENAME(oldpath
, newpath
);
347 char buffer1
[MAX_PATH
];
348 char buffer2
[MAX_PATH
];
351 dircache_rename(oldpath
, newpath
);
354 if(oldpath
[0] == '/') {
355 snprintf(buffer1
, sizeof(buffer1
), "%s%s", SIMULATOR_ARCHOS_ROOT
,
357 snprintf(buffer2
, sizeof(buffer2
), "%s%s", SIMULATOR_ARCHOS_ROOT
,
360 debugf("We rename the real file '%s' to '%s'\n", buffer1
, buffer2
);
361 return RENAME(buffer1
, buffer2
);
367 /* rockbox off_t may be different from system off_t */
368 long sim_lseek(int fildes
, long offset
, int whence
)
370 return lseek(fildes
, offset
, whence
);
373 long sim_filesize(int fd
)
376 return _filelength(fd
);
380 if (!fstat(fd
, &buf
))
387 void fat_size(unsigned int* size
, unsigned int* free
)
390 long secperclus
, bytespersec
, free_clusters
, num_clusters
;
392 if (GetDiskFreeSpace(NULL
, &secperclus
, &bytespersec
, &free_clusters
,
395 *size
= num_clusters
* secperclus
/ 2 * (bytespersec
/ 512);
397 *free
= free_clusters
* secperclus
/ 2 * (bytespersec
/ 512);
402 if (!statfs(".", &fs
)) {
403 DEBUGF("statfs: bsize=%d blocks=%ld free=%ld\n",
404 (int)fs
.f_bsize
, fs
.f_blocks
, fs
.f_bfree
);
406 *size
= fs
.f_blocks
* (fs
.f_bsize
/ 1024);
408 *free
= fs
.f_bfree
* (fs
.f_bsize
/ 1024);
419 int sim_fsync(int fd
)
430 #define dlopen(_x_, _y_) LoadLibraryW(UTF8_TO_OS(_x_))
431 #define dlsym(_x_, _y_) (void *)GetProcAddress(_x_, _y_)
432 #define dlclose(_x_) FreeLibrary(_x_)
438 #define TEMP_CODEC_FILE "archos/_temp_codec%d.dll"
440 void *sim_codec_load_ram(char* codecptr
, int size
,
441 void* ptr2
, int bufwrap
, void **pd
)
454 /* We have to create the dynamic link library file from ram so we
455 can simulate the codec loading. With voice and crossfade,
456 multiple codecs may be loaded at the same time, so we need
457 to find an unused filename */
458 for (codec_count
= 0; codec_count
< 10; codec_count
++)
460 snprintf(path
, sizeof(path
), TEMP_CODEC_FILE
, codec_count
);
462 fd
= OPEN(path
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, S_IRWXU
);
464 break; /* Created a file ok */
468 DEBUGF("failed to open for write: %s\n", path
);
475 copy_n
= bufwrap
< size
? bufwrap
: size
;
476 if (write(fd
, codecptr
, copy_n
) != copy_n
) {
477 DEBUGF("write failed");
482 if (write(fd
, ptr2
, size
) != size
) {
483 DEBUGF("write failed [2]");
489 /* Now load the library. */
490 *pd
= dlopen(path
, RTLD_NOW
);
492 DEBUGF("failed to load %s\n", path
);
494 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
495 buf
, sizeof buf
, NULL
);
496 DEBUGF("dlopen(%s): %s\n", path
, buf
);
498 DEBUGF("dlopen(%s): %s\n", path
, dlerror());
503 hdr
= dlsym(*pd
, "__header");
505 hdr
= dlsym(*pd
, "___header");
507 return hdr
; /* maybe NULL if symbol not present */
510 void sim_codec_close(void *pd
)
515 void *sim_plugin_load(char *plugin
, void **pd
)
523 snprintf(path
, sizeof(path
), "archos%s", plugin
);
527 *pd
= dlopen(path
, RTLD_NOW
);
529 DEBUGF("failed to load %s\n", plugin
);
531 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
532 buf
, sizeof(buf
), NULL
);
533 DEBUGF("dlopen(%s): %s\n", path
, buf
);
535 DEBUGF("dlopen(%s): %s\n", path
, dlerror());
540 hdr
= dlsym(*pd
, "__header");
542 hdr
= dlsym(*pd
, "___header");
544 return hdr
; /* maybe NULL if symbol not present */
547 void sim_plugin_close(void *pd
)
553 static unsigned old_cp
;
555 void debug_exit(void)
557 /* Reset console output codepage */
558 SetConsoleOutputCP(old_cp
);
561 void debug_init(void)
563 old_cp
= GetConsoleOutputCP();
564 /* Set console output codepage to UTF8. Only works
565 * correctly when the console uses a truetype font. */
566 SetConsoleOutputCP(65001);
570 void debug_init(void)
572 /* nothing to be done */
576 void debugf(const char *fmt
, ...)
580 vfprintf( stderr
, fmt
, ap
);
584 void ldebugf(const char* file
, int line
, const char *fmt
, ...)
588 fprintf( stderr
, "%s:%d ", file
, line
);
589 vfprintf( stderr
, fmt
, ap
);
593 /* rockbox off_t may be different from system off_t */
594 int sim_ftruncate(int fd
, long length
)
597 return _chsize(fd
, length
);
599 return ftruncate(fd
, length
);