
iznogoud
Members-
Posts
18 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Gallery
Downloads
Everything posted by iznogoud
-
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hello pete, Following my previous work on interrogating FS " from inside " I made several tests to try to measure how often I could make such interrogations. So I created a module that initiate a timer and try to interrogate FS. Some time measurement shows that time between 2 interrogations can't be lower than 60ms and can take as long as 130ms. My question is regarding the way a module action takes place in the run of FS program. -Is there a way to know when FS has a break//pause in his process to use that time in the module process? or should I continue to try to make any action when needed, not taking care of FS workload? -Is there a way to ask FS to execute a portion of a module repetitively not using any timer to trigger it? -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Yes, it's a delphi Unit. It's the translation of your ModuleUser.c file. Simply add it to the uses declaration in a delphi program, (same as FCPuser.pas in the sdk, and that's it. I'm gonna send it to your email. Regards, Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
unit internal; interface uses messages,windows,math,sysutils; const WM_IPCTHREADACCESS=WM_USER+130; LIB_VERSION=1200; MAX_SIZE=$7F00; FSUIPC_ERR_OK = 0; FSUIPC_ERR_OPEN = 1; // Attempt to Open when already Open FSUIPC_ERR_NOFS = 2; // Cannot link to FSUIPC or WideClient FSUIPC_ERR_VIEW = 6; // Failed to open a view to the file map FSUIPC_ERR_WRONGFS = 8; // Sim is not version requested FSUIPC_ERR_NOTOPEN = 9; // Call cannot execute, link not Open FSUIPC_ERR_NODATA = 10; // Call cannot execute: no requests accumulated FSUIPC_ERR_DATA = 13; // IPC request contains bad data FSUIPC_ERR_SIZE = 15; // Read or Write request cannot be added, memory for Process is full FS6IPC_MESSAGE_SUCCESS = 1; // IPC message types FS6IPC_READSTATEDATA_ID = 1; FS6IPC_WRITESTATEDATA_ID = 2; //Misc SIM_FS2K4 = 7; type pword= ^word; pbyte= ^byte; FS6IPC_READSTATEDATA_HDR=record dwId : dword; dwOffset : dword; nBytes : dword; pDest : pointer; end; FS6IPC_WRITESTATEDATA_HDR=record dwId : dword; dwOffset : dword; nBytes : dword; end; var FSUIPC_VERSION:word; FSUIPC_FS_Version:word; FSUIPC_Lib_Version:word; m_hwnd:hwnd=0; m_pview:pointer; m_pnext:pointer; m_ulMax:longword; procedure FSUIPC_Close; function FSUIPC_Open2(dwFSReq:word;var dwresult:Dword; pMem: pbyte; dwsize:word ):boolean; function FSUIPC_Process(var dwresult:dword):boolean; Function FSUIPC_ReadCommon(fspecial:boolean;dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; Function FSUIPC_Read(dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; Function FSUIPC_ReadSpecial(dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; Function FSUIPC_Write(dwOffset : DWORD; dwSize : DWORD; pSrce : Pointer; var dwResult : DWORD) : Boolean; implementation procedure FSUIPC_Close; begin m_hWnd:=0; m_pView:=nil; end; function FSUIPC_open2(dwFSReq:word;var dwresult:Dword; pMem: pbyte; dwsize:word ):boolean; begin // abort if already started if m_pview<>nil then begin dwresult:=FSUIPC_ERR_OPEN; FSUIPC_open2:=false; exit; end; if (pMem=nil) or (dwsize<32) then begin dwresult:=FSUIPC_ERR_VIEW; FSUIPC_open2:=false; exit; end; // Clear version information, so know when connected FSUIPC_FS_Version:=0; FSUIPC_Version:=FSUIPC_FS_Version; // Connect via FSUIPC, which is known to be FSUIPC's own // and isn't subject to user modificiation m_hWnd := FindWindowEx(0, 0, PChar('UIPCMAIN'), Nil); if m_hWnd=0 then begin dwResult:=FSUIPC_ERR_NOFS; FSUIPC_open2:=false; exit; end; // get an area of memory m_ulMax:=min(dwSize,MAX_SIZE); m_pView:=pMem; // Okay, now determine FSUIPC version AND FS type DWORD(m_pNext):=DWORD(m_pView) + 4; // Allow space for code pointer // Read FSUIPC version if FSUIPC_Read($3304, 4, @FSUIPC_Version, dwResult)=false then begin FSUIPC_Close; FSUIPC_open2:=false; exit; end; // and FS version and validity check pattern if FSUIPC_Read($3308, 4, @FSUIPC_FS_Version, dwResult)=false then begin FSUIPC_Close; FSUIPC_open2:=false; exit; end; // Write our Library version number to a special read-only offset // This is to assist diagnosis from FSUIPC logging if FSUIPC_Write($330a, 2, @FSUIPC_Lib_Version, dwResult)=false then begin FSUIPC_Close; FSUIPC_open2:=false; exit; end; // Actually send the requests and get the responses ("process") if FSUIPC_Process(dwResult)=false then begin FSUIPC_Close(); FSUIPC_open2:=false; exit; end; dwresult:=FSUIPC_ERR_OK; FSUIPC_open2:=true; end; function fsuipc_process(var dwresult:dword):boolean; var dwError : DWORD; pdw : ^DWORD; //Pointer; pHdrR : ^FS6IPC_READSTATEDATA_HDR; pHdrW : ^FS6IPC_WRITESTATEDATA_HDR; pTemp:^DWORD; begin if (m_pView = Nil) then begin dwResult := FSUIPC_ERR_NOTOPEN; Result := FALSE; Exit; end; if (DWORD(m_pView)+4 >= DWORD(m_pNext)) then begin dwResult := FSUIPC_ERR_NODATA; Result := FALSE; Exit; end; ZeroMemory(m_pNext, 4); // Terminator // send the request asm push eax call @next @next: pop eax mov dwError,eax pop eax end; dwError:= sendmessage(m_hwnd,WM_IPCTHREADACCESS,dword(m_pNext)-dword(m_pView)-4,dword(m_pView) ); dword(m_pnext):=dword(m_pView)+4; if dwError<>FS6IPC_MESSAGE_SUCCESS then begin dwResult:=FSUIPC_ERR_DATA; Result := FALSE; Exit; end; dword(pdw):=dword(m_pview)+4; while (pdw <> Nil) and Boolean(pdw^) do begin case pdw^ of FS6IPC_READSTATEDATA_ID : begin pHdrR := Pointer(pdw); DWORD(m_pNext) := DWORD(m_pNext) + sizeof(FS6IPC_READSTATEDATA_HDR); if (pHdrR^.pDest <> Nil) and (pHdrR^.nBytes <> 0) then begin CopyMemory(pHdrR^.pDest, m_pNext, pHdrR^.nBytes); end; DWORD(m_pNext) := DWORD(m_pNext) + pHdrR^.nBytes; end; FS6IPC_WRITESTATEDATA_ID : begin // This is a write, so there's no returned data to store pHdrW := Pointer(pdw); DWORD(m_pNext) := DWORD(m_pNext) + sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW^.nBytes; end; else // Error! So terminate the scan pdw := Nil; end; dword(pdw):=dword(m_pNext); end; dword(m_pNext) := dword(m_pView)+4; dwResult := FSUIPC_ERR_OK; Result := TRUE; end; Function FSUIPC_ReadCommon(fspecial:boolean;dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; var pHdr : ^FS6IPC_READSTATEDATA_HDR; begin dword(pHdr) := dword(m_pNext); // Check link is open if (m_pView = Nil) then begin dwResult := FSUIPC_ERR_NOTOPEN; Result := FALSE; Exit; end; // Check have space for this request (including terminator) if (((DWORD(m_pNext) - DWORD(m_pView)) + 8 + (dwSize + sizeof(FS6IPC_READSTATEDATA_HDR))) > m_ulMax) then begin dwResult := FSUIPC_ERR_SIZE; Result := FALSE; Exit; end; // Initialise header for read request pHdr^.dwId := FS6IPC_READSTATEDATA_ID; pHdr^.dwOffset := dwOffset; pHdr^.nBytes := dwSize; pHdr^.pDest := pDest; //update pointer DWORD(m_pNext) := DWORD(m_pNext) + sizeof(FS6IPC_READSTATEDATA_HDR); // Initialise the reception area, so rubbish won't be returned if (dwSize <> 0) then begin if fspecial=true then CopyMemory(m_pNext,pdest,dwsize) else ZeroMemory(m_pNext, dwSize); end; // Update the pointer ready for more data DWORD(m_pNext) := DWORD(m_pNext)+ dwsize; dwResult := FSUIPC_ERR_OK; Result := TRUE; end; Function FSUIPC_Read(dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; begin FSUIPC_ReadCommon(false,dwoffset,dwsize,pDest,dwResult); end; Function FSUIPC_ReadSpecial(dwOffset : DWORD; dwSize : DWORD; pDest : Pointer; var dwResult : DWORD) : Boolean; begin FSUIPC_ReadCommon(true,dwoffset,dwsize,pDest,dwResult); end; Function FSUIPC_Write(dwOffset : DWORD; dwSize : DWORD; pSrce : Pointer; var dwResult : DWORD) : Boolean; var pHdr : ^FS6IPC_WRITESTATEDATA_HDR; begin pHdr := m_pNext; if (m_pView = Nil) then begin dwResult := FSUIPC_ERR_NOTOPEN; Result := FALSE; Exit; end; // Check have space for this request (including terminator) if (((DWORD(m_pNext) - DWORD(m_pView)) + 8 +(dwSize + sizeof(FS6IPC_WRITESTATEDATA_HDR))) > m_ulMax) then begin dwResult := FSUIPC_ERR_SIZE; Result := FALSE; Exit; end; // Initialise header for write request pHdr^.dwId := FS6IPC_WRITESTATEDATA_ID; pHdr^.dwOffset := dwOffset; pHdr^.nBytes := dwSize; // Update the pointer ready for write dword(m_pNext):=dword(m_pNext)+ sizeof(FS6IPC_WRITESTATEDATA_HDR); // Copy in the data to be written if (dwSize<>0)then CopyMemory(m_pNext, pSrce, dwSize); // Update the pointer ready for more data dword(m_pNext):=dword(m_pNext)+dwSize; dwResult := FSUIPC_ERR_OK; Result := TRUE; end; Initialization //--- Initialize global variables --- FSUIPC_Version := 0; FSUIPC_FS_Version := 0; FSUIPC_Lib_Version := LIB_VERSION; //--- IPC Client Stuff --- m_hWnd := 0; // FS6 window handle m_pView := Nil; // pointer to view of file-mapping object m_pNext := Nil; finalization //--- Automatic "close" if programmer "forgets" --- FSUIPC_Close; end. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hi Pete, In these past days, and thanks to you, I have learnt lots of things. Now everything works fine !!! If you're interested in, I can send you my code if you want to add it to the next sdk. But first, I've to cleand up all the debugging stuff. Thanks a lot for your fast answers, Regards, Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
No sorry I can't. I mean, this is not a "program" that I can follow step by step, but a dll. so that I launch it on another PC with FS and collect the values using a file. well the problem is that the m_pview value is modified by dwerror just after the asm code: // send the request __asm { push eax call next next: pop eax mov dwError,eax pop eax } *((DWORD *) m_pView) = dwError; unless I'm wrong in understanding that, the value of dwerror is put into m_pView right? that's the reason of the changes. But I might be wrong in understanding the instruction: *((DWORD *) m_pView) = dwError; For the asm code: is it possible to replace it with standard code even if less efficient? -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Ok Pete. We're getting closer step by step. About error, yes, there is still one after the sendmessage function. But lets have a look. 1. the first DWORD should contain an address saved by the asm code: but there is nothing in it after the asm. Is it the only purpose of this asm code? 2. here are the values of m_pnext and m_pview just before the call to asm: there is a 58bytes difference and seems correct now. Here is the state of datas AFTER the asm code and BEFORE the sendmessage: We can see that: the first dword is empty the value of dwerror after the asm code the calculation of m_pNext-m_pView-4= 14492 Could such a value be correct? Is it normal that the m_pview pointer, that originally contained the address of the start of the memory block, is changed? the sendmessage function returns 0 and it should return 1 if no errors. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hi Pete, I've corrected lots of bugs. Main where relative to m_pnext pointer position update. There some things not clear: But in your source code, there is: // Okay, now determine FSUIPC version AND FS type m_pNext = m_pView + 4; // Allow space for code pointer this make a 4 bytes offset at the begining of the area, and explains (for me) the extra 0 DWORD. Should I remove that?? Now the problems you noticed in the data block was due to a bad translation of that code in delphi: CopyMemory(&m_pNext[sizeof(FS6IPC_READSTATEDATA_HDR)]. m_pnext was not updated to the end of the record and he was zeroing at the begining. ok this is corrected. Now here is what I get: Please Note that I tried with and without the 0 DWORD at the beginning and I have the error at each time. In the send message function, what does the Wparam represent exactly? Regards, Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hi Pete I did make the conversion using the help of the delphi SDK of course. But I stil have the problem. Here is what happens. I define an array of byte with size as 74. I simply try to call FSUIPC_OPEN2(SIM_FS2K4, dwResult,pmem,dwsize) with pmem pointing on the byte array and dwsize=74 (checked). Everything goes right (calls to read x2 and to write ) until the program reaches the fsuipc_process call that is inside the open2 function. I dumped out some data just after the assembler block. Here is what I get: Hope it could get some light to you on my problem... -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
--- POST EDITED 15:58 --- Ok, your post made me realize some things. In the call to FSUIPC_open2 I provide a pointer to an array of bytes, with the correct size (I hope) for my expexted following request. As I only want to read magvar and heading I calculate the size to be magvar(2)+16+heading(4)+16+ 16more that makes 54 bytes. please tell me if I'm wrong) I call FSUIPC_open2(...) FSUIPC_read(heading...) FSUIPC_read(magvar...) FSUIPC_process The problem in fact is that inside the FSUIPC_open2 call there are already some call to read/write functions, and the FSUIPC_WRITE call inside The open2 run short of memory space !! I think there is something I really did not catch!! I might be wrong in the way I calculate the memory. So, for test, I decided only to call for the FSUIPC_open 2 function allowing a memory of 74bytes. And in fact now the program exits with a failure during the fsuipc_process call inside the open2 function. I'm gonna investigate more to see where exactly if fails, and I'll make a dump of the memory space at this moment. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hi Pete, I've translated all the code (probably with a mistake of course). I've an error at execution during FSUIPC_PROCESS. It occurs when sending the message after the asm execution. Error code is FS6IPC_MESSAGE_FAILURE At this moment the value in DWORD(m_pview)=30467134 Any idea on how to investigate for what can cause that error? As it runs in FS process it's not easy to debug and the only thing I was able to do for the moment is to flush some variable content to see what's in. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Ok, Thanks! This also compiles correctly If I place the call before. I'm gonna try the module before the end of the afternoon, I'll let you know. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Ok, I investigate the call function and labels. This code compiles in delphi: asm push eax @next: pop eax call @next mov dwError,eax pop eax end; Do you think this could be ok ? (it seems I can't use the $+5 instruction) -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Hi Pete. I began to translate into delphi your library for internal access to FS. My only last problem is with the assembler code: { push eax call next next: pop eax mov dwError,eax pop eax } The use of asm is possible in delphi. I simply put your code like that, but I get an error message: identifier not declared: next Seems the declaration of "next:" is not compatible with delphi asm instructions. I do not understand a thing in asm. Would there be another way to write that part of code? could you "translate in english" what this operation do? Thanks for your help, Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Well Pete, I'm really sorry to disturb, but reading the doc is the first thing I did. The problem is that for non C programmer, the only header of the FSUIPC_OPEN2 function is not very clear. You know, use of pointers in delphi is something not common due to the structure of the language. As it is not in the Delphi sdk, I do not really understand how to use it. Anyway also read anoter readme called FSUIPC_Internal_Access.txt . I'd like to try that way, but once again I have questions(sorry): If I understand everything, it's made through the use of windows messages. Then, where to find the value of WM_USER? What is the exact structure of pDATA ?. sorry to ask, but a standard call to FSUIPC_READ in delphi calls for both a pointer to receive the data and the offset value. Here, is the offset value included in the pDATA? Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
-- -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
Will do Pete. I would have only 2 questions: I tried to make a test module to interrogate FSUIPC from within FS. It works using the standard FSUIPC_Open call. Where can I find info about FSUIPC_open2 ? and what could be the problem if i only use the FSUIPC_open version? (seems this is not documented in the delphi SDK) Is there a way to know (from within FS) when FS actualized it's datas? (like a windows message or so?) Thanks for your help, Michael. -
FSUIPC, client/server interface?
iznogoud replied to iznogoud's topic in FSUIPC Support Pete Dowson Modules
To keep a compatibility is a good thing. But it cannot be the only reason to let things unchanged. I really understand (and respect) all the work that has been done. I just think about the way datas are delivered to client application. Even if the concept of FSUIPC was not changed, maybe it could be possible to think about changing the WideFS principles (or to add a sort of option)? In a way where any client could be able to receive the datas directly on the network instead of interrogating. Could you maybe give a little more details on how datas are exchanged between wideclient and wideserver? I assume that datas are sent from/to both program. Would it be possible to catch datas directly on the network? This would be really more close to real time handling. As I read from you, acces to variables through IPC can be a very long process. Regards, Michael. There are other sims who delivered datas that way, using UDP. No doubt that if MS release next version of FS which such features, developpers will use it. But I could bet that MS won't do that. Anyway, it doesn't prevent me from thinking that for more performance, a network solution would be better. So to answer your question, why don't I do that myself?Although I could deal with the transport layer, I do not have the necessary knowledges to find datas in FS like you do. That's why I ask. Do not get blessed, Peter, I had no idea at all to criticise your work. -
Hi Pete, I was wondering (may be a stupid question) why FSUIPC would not change into a client/server application ? I mean that I do not find very interesting for real time developpement, to be obliged to check all the variables by a call to FSUIPC at constant time interval. If lots of applications are running, it increases the load on FSUIPC even if nothing changed. I'd really prefer to listen to a network port for pack of data to arrive when they 're changing inside FS. At a software connection, the server could then send all the data in one block for initialisation. Your opinion Peter? Regards, ;) Michael.