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;
40 default: // Defaults to output
41 case '>': direction = 1; break;
42 case '<': direction = 2; break;
43 case '?': direction = 3; break;
48 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
49 if( *ArgTypes == '\0' ) return ArgTypes;
57 if( direction != 1 ) {
58 Warning("ReadEntry: Recieving an integer is not defined");
62 val32 = va_arg(*Args, uint32_t);
64 Dest->Type = ARG_TYPE_INT32;
65 Dest->Length = sizeof(uint32_t);
69 *(uint32_t*)DataDest = val32;
74 if( direction != 1 ) {
75 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
79 val64 = va_arg(*Args, uint64_t);
81 Dest->Type = ARG_TYPE_INT64;
82 Dest->Length = sizeof(uint64_t);
85 *(uint64_t*)DataDest = val64;
89 // Input string makes no sense!
90 if( direction != 1 ) {
91 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
95 str = va_arg(*Args, char*);
97 Dest->Type = ARG_TYPE_STRING;
98 Dest->Length = strlen(str) + 1;
103 memcpy(DataDest, str, Dest->Length);
106 // Data (special handling)
108 len = va_arg(*Args, int);
109 str = va_arg(*Args, char*);
111 // Save the pointer for later
112 if( PtrDest ) *PtrDest = str;
114 // Create parameter block
115 Dest->Type = ARG_TYPE_DATA;
119 Dest->Flags |= ARG_FLAG_RETURN;
125 memcpy(DataDest, str, len);
128 Dest->Flags |= ARG_FLAG_ZEROED;
142 * Whitespace is ignored
143 * >i: Input Integer (32-bits)
144 * >I: Input Long Integer (64-bits)
146 * >d: Input Buffer (Preceded by valid size)
147 * <I: Output long integer
148 * <d: Output Buffer (Preceded by valid size)
149 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
152 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
155 int paramCount, dataLength;
156 int retCount = 1, retLength = sizeof(uint64_t);
157 void **retPtrs; // Pointers to return buffers
165 // printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
166 // printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
167 // printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
170 va_start(args, ArgTypes);
176 tRequestValue tmpVal;
178 str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
180 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
184 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
185 dataLength += tmpVal.Length;
187 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
188 retLength += tmpVal.Length;
194 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
195 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
198 retPtrs = malloc( sizeof(void*) * (retCount+1) );
199 if( dataLength > retLength)
200 req = malloc( dataLength );
202 req = malloc( retLength );
203 req->ClientID = 0; //< Filled later
204 req->CallID = SyscallID;
205 req->NParams = paramCount;
206 dataPtr = &req->Params[paramCount];
208 // Fill `output` and `input`
209 va_start(args, ArgTypes);
211 // - re-zero so they can be used as indicies
216 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
219 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
220 dataPtr += req->Params[paramCount].Length;
221 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
228 // Send syscall request
229 if( SendRequest(req, dataLength, retLength) < 0 ) {
230 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
234 // Parse return value
235 dataPtr = &req->Params[req->NParams];
237 if( req->NParams >= 1 )
239 switch(req->Params[0].Type)
242 retValue = *(uint64_t*)dataPtr;
243 dataPtr += req->Params[0].Length;
246 retValue = *(uint32_t*)dataPtr;
247 dataPtr += req->Params[0].Length;
252 // Write changes to buffers
254 for( i = 1; i < req->NParams; i ++ )
258 printf("Return Data %i: (%i)", i, req->Params[i].Length);
259 for( j = 0; j < req->Params[i].Length; j ++ )
260 printf(" %02x", ((uint8_t*)dataPtr)[j]);
263 memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
264 dataPtr += req->Params[i].Length;
270 DEBUG(": %llx", retValue);
276 int native_open(const char *Path, int Flags)
279 for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ;
280 if(ret == MAX_FPS) return -1;
281 // TODO: Handle directories
282 gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+");
283 if(!gaSyscall_LocalFPs[ret]) return -1;
287 void native_close(int FD)
289 fclose( gaSyscall_LocalFPs[FD] );
290 gaSyscall_LocalFPs[FD] = NULL;
293 size_t native_read(int FD, void *Dest, size_t Bytes)
295 return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] );
298 size_t native_write(int FD, const void *Src, size_t Bytes)
300 return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD] );
303 int native_seek(int FD, int64_t Ofs, int Dir)
306 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_CUR );
308 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_SET );
310 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_END );
313 uint64_t native_tell(int FD)
315 return ftell( gaSyscall_LocalFPs[FD] );