unit kern_ipmimgr; {$mode ObjFPC}{$H+} {$CALLING SysV_ABI_CDecl} interface function sys_ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; implementation uses sysutils, errno, systm, subr_backtrace, kern_named_id; type p_IpmiClientCreateData=^t_IpmiClientCreateData; t_IpmiClientCreateData=packed record size :QWORD; f_0x8 :DWORD; _align1:Integer; f_0x10 :QWORD; f_0x18 :QWORD; f_0x20 :DWORD; _align2:Integer; f_0x28 :QWORD; f_0x30 :QWORD; acount :DWORD; _align3:Integer; f_0x100:array[0..31] of QWORD; f_0x140:DWORD; f_0x144:DWORD; f_0x148:QWORD; end; p_syscallCreateClien=^t_syscallCreateClient; t_syscallCreateClient=packed record this:Pointer; name:pchar; data:p_IpmiClientCreateData; end; function syscallCreateClient(src:p_syscallCreateClien;dst:PInteger):Integer; var name:t_id_name; data:t_IpmiClientCreateData; kid:Integer; begin name:=Default(t_id_name); Result:=copyinstr(src^.name,@name,25,nil); if (Result<>0) then Exit; if (name[24]<>#0) then Exit(ENAMETOOLONG); if (src^.data=nil) then Exit(EINVAL); data:=Default(t_IpmiClientCreateData); Result:=copyin(src^.data,@data,SizeOf(data)); if (Result<>0) then Exit; if (data.size > $150) then Exit(EINVAL); if (data.f_0x8 > $10) then Exit(EINVAL); Writeln('syscallCreateClient(',HexStr(src^.this),',"',name,'")'); kid:=222; dst^:=kid; end; type p_syscallConnectWithWaitServer=^t_syscallConnectWithWaitServer; t_syscallConnectWithWaitServer=packed record param_0:QWORD; param_1:QWORD; pRes :PInteger; //out param_3:PInteger; //in end; function syscallConnectWithWaitServer(kid:Integer;src:p_syscallConnectWithWaitServer;dst:PInteger):Integer; var kval:Integer; begin if (src^.pRes=nil) then Exit(EINVAL); if (src^.param_0=0) then begin if (src^.param_1<>0) then begin Exit(EINVAL); end; end else if ((src^.param_1 - 1) > $1fff) then begin Exit(EINVAL); end; if (src^.param_3<>nil) then begin Result:=copyin(src^.param_3,@kval,SizeOf(Integer)); if (Result<>0) then Exit; end; Writeln('syscallConnectWithWaitServer(',kid,',', HexStr(src^.param_0,16),',', HexStr(src^.param_1,16),',', HexStr(src^.pRes),',', HexStr(src^.param_3),',', kval,')'); kval:=0; Result:=copyout(@kval,src^.pRes,SizeOf(Integer)); dst^:=0; Result:=0; end; type p_IpmiBufferInfo=^t_IpmiBufferInfo; t_IpmiBufferInfo=packed record data:Pointer; size:QWORD; prm3:QWORD; end; p_IpmiDataInfo=^t_IpmiDataInfo; t_IpmiDataInfo=packed record data:Pointer; size:QWORD; end; p_IpmiSyncCallParams=^t_IpmiSyncCallParams; t_IpmiSyncCallParams=packed record method :DWORD; dataCount :DWORD; bufCount :DWORD; align1 :DWORD; pData :p_IpmiDataInfo; pBuffers :p_IpmiBufferInfo; pResult :PInteger; resultCount:DWORD; align2 :DWORD; end; //[NpMgrIpcCli] (method=0):get EventFlag const NpEvent:PChar='NpMgrEvent'; function syscallSendReceiveInvokeSyncMethod(kid:Integer;src:p_IpmiSyncCallParams;dst:PInteger):Integer; begin if (src^.dataCount >10) then Exit(EINVAL); if (src^.bufCount >10) then Exit(EINVAL); if (src^.resultCount>1) then Exit(EINVAL); Writeln('syscallSendReceiveInvokeSyncMethod(',kid,',', src^.method,',', src^.dataCount,',', src^.bufCount,',', src^.resultCount,')'); case src^.method of 0:begin Result:=copyout(NpEvent,src^.pBuffers[0].data,Length(NpEvent)); end; else; end; dst^:=0; Result:=0; end; type p_syscallPollEventFlag=^t_syscallPollEventFlag; t_syscallPollEventFlag=packed record unk_id :Integer; _align1 :Integer; bitPattern:QWORD; waitMode :DWORD; _align2 :Integer; pRes :PQWORD; end; function syscallPollEventFlag(kid:Integer;src:p_syscallPollEventFlag;dst:PInteger):Integer; var kval:QWORD; begin Writeln('syscallPollEventFlag(',kid,',', src^.unk_id,',', src^.bitPattern,',', src^.waitMode,')'); kval:=0; Result:=copyout(@kval,src^.pRes,SizeOf(QWORD)); dst^:=0; Result:=0; end; function sys_ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; label _copyout; type t_src=array[0..7] of QWORD; var dst:Integer; src:t_src; begin Result:=0; dst:=0; Writeln('sys_ipmimgr_call(',op,',',kid,',',paramsSize,')'); if (paramsSize > 64) then begin dst:=-2146566143; goto _copyout; end; src:=Default(t_src); case op of 2: //syscallCreateClient begin Result:=copyin(params,@src,paramsSize); if (Result<>0) then Exit; Result:=syscallCreateClient(@src,@dst); end; 1024: //syscallConnectWithWaitServer begin Result:=copyin(params,@src,paramsSize); if (Result<>0) then Exit; Result:=syscallConnectWithWaitServer(kid,@src,@dst); end; 800: //syscallSendReceiveInvokeSyncMethod begin Result:=copyin(params,@src,paramsSize); if (Result<>0) then Exit; Result:=syscallSendReceiveInvokeSyncMethod(kid,@src,@dst); end; 1169: //syscallPollEventFlag begin Result:=copyin(params,@src,paramsSize); if (Result<>0) then Exit; Result:=syscallPollEventFlag(kid,@src,@dst); end; else begin Result:=0; dst:=-1; print_error_td('sys_ipmimgr_call('+IntToStr(op)+')'); Assert(False); end; end; if (Result=0) then begin _copyout: Result:=copyout(@dst,res,SizeOf(Integer)); end; end; end.