3 #define DONT_INCLUDE_SYSCALL_NAMES 1
13 #define DEBUG(str, x...) Debug(str, x)
22 FILE *gaSyscall_LocalFPs[MAX_FPS];
25 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
29 int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out
34 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
35 if( *ArgTypes == '\0' ) return ArgTypes;
37 // DEBUG("ArgTypes = '%s'", ArgTypes);
42 default: // Defaults to output
43 case '>': direction = 1; break;
44 case '<': direction = 2; break;
45 case '?': direction = 3; break;
50 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
51 if( *ArgTypes == '\0' ) return ArgTypes;
59 if( direction != 1 ) {
60 Warning("ReadEntry: Recieving an integer is not defined");
64 val32 = va_arg(*Args, uint32_t);
66 Dest->Type = ARG_TYPE_INT32;
67 Dest->Length = sizeof(uint32_t);
71 *(uint32_t*)DataDest = val32;
76 if( direction != 1 ) {
77 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
81 val64 = va_arg(*Args, uint64_t);
83 Dest->Type = ARG_TYPE_INT64;
84 Dest->Length = sizeof(uint64_t);
87 *(uint64_t*)DataDest = val64;
91 // Input string makes no sense!
92 if( direction != 1 ) {
93 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
97 str = va_arg(*Args, char*);
99 Dest->Type = ARG_TYPE_STRING;
100 Dest->Length = strlen(str) + 1;
105 memcpy(DataDest, str, Dest->Length);
108 // Data (special handling)
110 len = va_arg(*Args, int);
111 str = va_arg(*Args, char*);
113 // Save the pointer for later
114 if( PtrDest ) *PtrDest = str;
116 // Create parameter block
117 Dest->Type = ARG_TYPE_DATA;
121 Dest->Flags |= ARG_FLAG_RETURN;
127 memcpy(DataDest, str, len);
130 Dest->Flags |= ARG_FLAG_ZEROED;
144 * Whitespace is ignored
145 * >i: Input Integer (32-bits)
146 * >I: Input Long Integer (64-bits)
148 * >d: Input Buffer (Preceded by valid size)
149 * <I: Output long integer
150 * <d: Output Buffer (Preceded by valid size)
151 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
154 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
157 int paramCount, dataLength;
158 int retCount = 1, retLength = sizeof(uint64_t);
159 void **retPtrs; // Pointers to return buffers
167 // printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
168 // printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
169 // printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
172 va_start(args, ArgTypes);
178 tRequestValue tmpVal;
180 str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
182 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
186 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
187 dataLength += tmpVal.Length;
189 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
190 retLength += tmpVal.Length;
196 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
197 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
200 retPtrs = malloc( sizeof(void*) * (retCount+1) );
201 if( dataLength > retLength)
202 req = malloc( dataLength );
204 req = malloc( retLength );
205 req->ClientID = 0; //< Filled later
206 req->CallID = SyscallID;
207 req->NParams = paramCount;
208 dataPtr = &req->Params[paramCount];
210 // Fill `output` and `input`
211 va_start(args, ArgTypes);
213 // - re-zero so they can be used as indicies
218 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
221 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
222 dataPtr += req->Params[paramCount].Length;
223 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
230 // Send syscall request
231 if( SendRequest(req, dataLength, retLength) < 0 ) {
232 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
236 // Parse return value
237 dataPtr = &req->Params[req->NParams];
239 if( req->NParams >= 1 )
241 switch(req->Params[0].Type)
244 retValue = *(uint64_t*)dataPtr;
245 dataPtr += req->Params[0].Length;
248 retValue = *(uint32_t*)dataPtr;
249 dataPtr += req->Params[0].Length;
254 // Write changes to buffers
256 for( i = 1; i < req->NParams; i ++ )
260 printf("Return Data %i: (%i)", i, req->Params[i].Length);
261 for( j = 0; j < req->Params[i].Length; j ++ )
262 printf(" %02x", ((uint8_t*)dataPtr)[j]);
265 memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
266 dataPtr += req->Params[i].Length;
272 DEBUG(": %llx", retValue);
278 int native_open(const char *Path, int Flags)
281 for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ;
282 if(ret == MAX_FPS) return -1;
283 // TODO: Handle directories
284 gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+");
285 if(!gaSyscall_LocalFPs[ret]) return -1;
289 void native_close(int FD)
291 fclose( gaSyscall_LocalFPs[FD] );
292 gaSyscall_LocalFPs[FD] = NULL;
295 size_t native_read(int FD, void *Dest, size_t Bytes)
297 return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] );
300 size_t native_write(int FD, const void *Src, size_t Bytes)
302 return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD] );
305 int native_seek(int FD, int64_t Ofs, int Dir)
308 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_CUR );
310 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_SET );
312 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_END );
315 uint64_t native_tell(int FD)
317 return ftell( gaSyscall_LocalFPs[FD] );