filename | src/dcload.c |
changeset | 736:a02d1475ccfd |
prev | 671:a530ea88eebd |
next | 1065:bc1cc0c54917 |
author | nkeynes |
date | Wed Jun 24 06:06:40 2009 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Support shell substitutions in config paths Keep track of last folder in file dialogs Fix out-of-dateness in GTK path dialog |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * DC-load syscall implementation.
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <fcntl.h>
23 #include "dream.h"
24 #include "mem.h"
25 #include "dreamcast.h"
26 #include "syscall.h"
27 #include "sh4/sh4.h"
29 #define SYS_READ 0
30 #define SYS_WRITE 1
31 #define SYS_OPEN 2
32 #define SYS_CLOSE 3
33 #define SYS_CREAT 4
34 #define SYS_LINK 5
35 #define SYS_UNLINK 6
36 #define SYS_CHDIR 7
37 #define SYS_CHMOD 8
38 #define SYS_LSEEK 9
39 #define SYS_FSTAT 10
40 #define SYS_TIME 11
41 #define SYS_STAT 12
42 #define SYS_UTIME 13
43 #define SYS_ASSIGNWRKMEM 14
44 #define SYS_EXIT 15
45 #define SYS_OPENDIR 16
46 #define SYS_CLOSEDIR 17
47 #define SYS_READDIR 18
48 #define SYS_GETHOSTINFO 19
50 #define SYS_MAGIC 0xDEADBEEF
51 #define SYS_MAGIC_ADDR 0x8c004004
52 #define SYSCALL_ADDR 0x8c004008
54 static gboolean dcload_allow_unsafe = FALSE;
56 void dcload_set_allow_unsafe( gboolean allow )
57 {
58 dcload_allow_unsafe = allow;
59 }
61 #define MAX_OPEN_FDS 16
62 /**
63 * Mapping from emulator fd to real fd (so we can limit read/write
64 * to only fds we've explicitly granted access to).
65 */
66 int open_fds[MAX_OPEN_FDS];
68 int dcload_alloc_fd()
69 {
70 int i;
71 for( i=0; i<MAX_OPEN_FDS; i++ ) {
72 if( open_fds[i] == -1 ) {
73 return i;
74 }
75 }
76 return -1;
77 }
79 void dcload_syscall( uint32_t syscall_id )
80 {
81 // uint32_t syscall = sh4r.r[4];
82 int fd;
83 switch( sh4r.r[4] ) {
84 case SYS_READ:
85 fd = sh4r.r[5];
86 if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
87 sh4r.r[0] = -1;
88 } else {
89 sh4ptr_t buf = mem_get_region( sh4r.r[6] );
90 int length = sh4r.r[7];
91 sh4r.r[0] = read( open_fds[fd], buf, length );
92 }
93 break;
94 case SYS_WRITE:
95 fd = sh4r.r[5];
96 if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
97 sh4r.r[0] = -1;
98 } else {
99 sh4ptr_t buf = mem_get_region( sh4r.r[6] );
100 int length = sh4r.r[7];
101 sh4r.r[0] = write( open_fds[fd], buf, length );
102 }
103 break;
104 case SYS_LSEEK:
105 fd = sh4r.r[5];
106 if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
107 sh4r.r[0] = -1;
108 } else {
109 sh4r.r[0] = lseek( open_fds[fd], sh4r.r[6], sh4r.r[7] );
110 }
111 break;
113 /* Secure access only */
114 case SYS_OPEN:
115 if( dcload_allow_unsafe ) {
116 fd = dcload_alloc_fd();
117 if( fd == -1 ) {
118 sh4r.r[0] = -1;
119 } else {
120 char *filename = (char *)mem_get_region( sh4r.r[5] );
121 int realfd = open( filename, sh4r.r[6] );
122 open_fds[fd] = realfd;
123 sh4r.r[0] = realfd;
124 }
125 } else {
126 ERROR( "Denying access to local filesystem" );
127 sh4r.r[0] = -1;
128 }
129 break;
130 case SYS_CLOSE:
131 if( dcload_allow_unsafe ) {
132 fd = sh4r.r[5];
133 if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
134 sh4r.r[0] = -1;
135 } else {
136 if( open_fds[fd] > 2 ) {
137 sh4r.r[0] = close( open_fds[fd] );
138 } else {
139 /* Don't actually close real fds 0-2 */
140 sh4r.r[0] = 0;
141 }
142 open_fds[fd] = -1;
143 }
144 }
145 break;
146 case SYS_EXIT:
147 if( dcload_allow_unsafe ) {
148 dreamcast_shutdown();
149 exit( sh4r.r[5] );
150 } else {
151 dreamcast_stop();
152 }
153 default:
154 sh4r.r[0] = -1;
155 }
157 }
159 void dcload_install()
160 {
161 memset( &open_fds, -1, sizeof(open_fds) );
162 open_fds[0] = 0;
163 open_fds[1] = 1;
164 open_fds[2] = 2;
165 syscall_add_hook_vector( 0xF0, SYSCALL_ADDR, dcload_syscall );
166 mem_write_long( SYS_MAGIC_ADDR, SYS_MAGIC );
167 }
.