3 #include "../../Usermode/include/acess/sys.h"
11 #include "../syscalls.h"
18 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list Args)
22 int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out
27 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
28 if( *ArgTypes == '\0' ) return ArgTypes;
33 default: // Defaults to output
34 case '>': direction = 1; break;
35 case '<': direction = 2; break;
36 case '?': direction = 3; break;
41 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
42 if( *ArgTypes == '\0' ) return ArgTypes;
50 if( direction != 1 ) {
51 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
55 val32 = va_arg(Args, uint32_t);
57 Dest->Type = ARG_TYPE_INT32;
58 Dest->Length = sizeof(uint32_t);
62 *(uint32_t*)DataDest = val32;
67 if( direction != 1 ) {
68 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
72 val64 = va_arg(Args, uint64_t);
74 Dest->Type = ARG_TYPE_INT64;
75 Dest->Length = sizeof(uint64_t);
78 *(uint64_t*)DataDest = val64;
82 // Input string makes no sense!
83 if( direction != 1 ) {
84 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
88 str = va_arg(Args, char*);
90 Dest->Type = ARG_TYPE_STRING;
91 Dest->Length = strlen(str) + 1;
96 memcpy(DataDest, str, Dest->Length);
99 // Data (special handling)
101 len = va_arg(Args, int);
102 str = va_arg(Args, char*);
104 // Save the pointer for later
105 if( PtrDest ) *PtrDest = str;
107 // Create parameter block
108 Dest->Type = ARG_TYPE_INT64;
109 Dest->Length = sizeof(uint64_t);
112 Dest->Flags |= ARG_FLAG_RETURN;
118 memcpy(DataDest, str, len);
121 Dest->Flags |= ARG_FLAG_ZEROED;
135 * Whitespace is ignored
136 * >i: Input Integer (32-bits)
137 * >I: Input Long Integer (64-bits)
139 * >d: Input Buffer (Preceded by valid size)
140 * <I: Output long integer
141 * <d: Output Buffer (Preceded by valid size)
142 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
145 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
148 int paramCount, dataLength;
149 int retCount = 1, retLength = sizeof(uint64_t);
150 void **retPtrs; // Pointers to return buffers
158 va_start(args, ArgTypes);
164 tRequestValue tmpVal;
166 str = ReadEntry(&tmpVal, NULL, NULL, str, args);
168 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
172 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
173 dataLength += tmpVal.Length;
175 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
176 retLength += tmpVal.Length;
182 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
183 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
186 retPtrs = malloc( sizeof(void*) * (retCount+1) );
187 if( dataLength > retLength)
188 req = malloc( dataLength );
190 req = malloc( retLength );
191 req->ClientID = 0; //< Filled later
192 req->CallID = SyscallID;
193 req->NParams = paramCount;
194 dataPtr = &req->Params[paramCount];
196 // Fill `output` and `input`
197 va_start(args, ArgTypes);
199 // - re-zero so they can be used as indicies
204 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, args);
207 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
208 dataPtr += req->Params[paramCount].Length;
209 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
216 // Send syscall request
217 if( SendRequest(req, dataLength) ) {
218 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
222 // Parse return value
223 dataPtr = &req->Params[req->NParams];
225 if( req->NParams > 1 )
227 switch(req->Params[0].Type)
230 retValue = *(uint64_t*)dataPtr;
231 dataPtr += req->Params[0].Length;
234 retValue = *(uint32_t*)dataPtr;
235 dataPtr += req->Params[0].Length;
240 // Write changes to buffers
241 va_start(args, ArgTypes);
242 for( i = 1; i < req->NParams; i ++ )
244 memcpy( retPtrs[i-1], dataPtr, req->Params[i].Length );
245 dataPtr += req->Params[i].Length;
255 int open(const char *Path, int Flags) {
256 return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
260 _Syscall(SYS_CLOSE, ">i", FD);
263 size_t read(int FD, size_t Bytes, void *Dest) {
264 return _Syscall(SYS_READ, "<i >i >i <d", FD, Bytes, Bytes, Dest);
267 size_t write(int FD, size_t Bytes, void *Src) {
268 return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
271 int seek(int FD, int64_t Ofs, int Dir) {
272 return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
275 uint64_t tell(int FD) {
276 return _Syscall(SYS_TELL, ">i", FD);
279 int ioctl(int fd, int id, void *data) {
281 // NOTE: 1024 byte size is a hack
282 _Syscall(SYS_IOCTL, "<i >i >i ?d", &ret, fd, id, 1024, data);
285 int finfo(int fd, t_sysFInfo *info, int maxacls) {
287 _Syscall(SYS_FINFO, "<i >i <d >i",
289 sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
294 int readdir(int fd, char *dest) {
296 _Syscall(SYS_READDIR, "<i >i <d", &ret, fd, 256, dest);
300 int _SysOpenChild(int fd, char *name, int flags) {
302 _Syscall(SYS_OPENCHILD, "<i >i >s >i", &ret, fd, name, flags);
306 int _SysGetACL(int fd, t_sysACL *dest) {
308 _Syscall(SYS_GETACL, "<i >i <d", &ret, fd, sizeof(t_sysACL), dest);
312 int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
314 _Syscall(SYS_MOUNT, "<i >s >s >s >s", &ret, Device, Directory, Type, Options);
320 int _SysSetFaultHandler(int (*Handler)(int)) {
325 // === Symbol List ===
326 #define DEFSYM(name) {#name, name}
327 const tSym caBuiltinSymbols[] = {
339 DEFSYM(_SysOpenChild),
343 {"_SysSetFaultHandler", _SysSetFaultHandler}
346 const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);