Page 1 of 1

Simple IPC

Posted: Tue Jan 29, 2008 11:13 am
by Inf0Byt3
A simple IPC mechanism. IPCInit() is used only if you need to access the channels from a restricted account (not admin).

Code: Select all


;Simple IPC by Inf0Byt3
;29 Jan 2008
;Free for any use but don't blame me if something bad happens
;Credits appreciated but not necessary 

#MaxString = 1024

Global SD.SECURITY_DESCRIPTOR
Global SA.SECURITY_ATTRIBUTES

Global Initiated.b = 0

Procedure.l IPCInit()

 If InitializeSecurityDescriptor_(@SD, #SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl_(@SD, #True, #Null, #False)
  SA\nLength = SizeOf(SECURITY_ATTRIBUTES);
  SA\bInheritHandle = #False;
  SA\lpSecurityDescriptor = @SD;
  Initiated = 1
  ProcedureReturn 1
 Else
  Initiated = 0
  ProcedureReturn 0
 EndIf

EndProcedure 

Procedure.l IPCSendString(MapFileName.s, String.s)
  
  Protected ReturnValue = #False
  
  If Initiated = 1
   MapFileHandle = CreateFileMapping_($FFFFFFFF,0,#PAGE_READWRITE,0,#MaxString,MapFileName)
  Else
   MapFileHandle = CreateFileMapping_($FFFFFFFF,@SD,#PAGE_READWRITE,0,#MaxString,MapFileName)
  EndIf
  
  If MapFileHandle
    
    *MapFilePointer = MapViewOfFile_(MapFileHandle,#FILE_MAP_ALL_ACCESS,#Null,#Null,#MaxString)
    
    If *MapFilePointer <> #Null
      PokeS(*MapFilePointer,String,#MaxString)
      UnmapViewOfFile_(*MapFilePointer)
      ReturnValue = MapFileHandle
    EndIf

  EndIf
  
  ProcedureReturn ReturnValue
  
EndProcedure 

Procedure.s IPCReceiveString(MapFileName.s)

  Protected ReturnValue.s = ""

  MapFileHandle = OpenFileMapping_(#FILE_MAP_ALL_ACCESS,0,MapFileName)
  
  If MapFileHandle

    *MapFilePointer = MapViewOfFile_(MapFileHandle,#FILE_MAP_ALL_ACCESS,#Null,#Null,#Null)
    
    If *MapFilePointer <> #Null
      ReturnValue = PeekS(*MapFilePointer,#MaxString)
      UnmapViewOfFile_(MapFileHandle)
      CloseHandle_(MapFileHandle)
    EndIf
    
  EndIf
  
  ProcedureReturn ReturnValue
  
EndProcedure 

Procedure IPCCloseMap(MapFileHandle.l)

 If MapFileHandle > 0
  CloseHandle_(MapFileHandle)
 EndIf

EndProcedure

For Try = 0 To 9
 Handle = IPCSendString("A_MAP_FILE"+Str(Try), "This is a test"+Str(Try))
 Debug IPCReceiveString("A_MAP_FILE"+Str(Try))
 IPCCloseMap(Handle)
 Debug "---------------------------------------------------"
Next

Posted: Tue Jan 29, 2008 1:17 pm
by pdwyer
This looks interesting!

You can use this "Inter Process" I gather from the name?

I have never really used any of this kind of stuff before, could you explain a little about it. Can you get "wires crossed" due to the naming of the channnels? what are the limitations?

Thanks, sorry of the questions seem kind of basic

Posted: Tue Jan 29, 2008 1:34 pm
by Inf0Byt3
I made it even more simple. Yup, you can use it to communicate between two processes and exchange strings.

A 2 process example:

Code: Select all

XIncludeFile "IPC.pbi"

IPCInit()

IPCSendString("JUST_A_TEST","this is a string")

Repeat
 Delay(1)
Until IPCReceiveString("JUST_A_TEST") = "aha!"
Debug "received: "+"aha! QUITING"
and process 2:

Code: Select all

XIncludeFile "IPC.pbi"

Repeat
 Delay(1)
Until IPCReceiveString("JUST_A_TEST") = "this is a string"
Debug "received: "+"this is a string"

IPCSendString("JUST_A_TEST", "aha!")
Debug "sent: "+"aha!"
To test, run p1 than p2. All this does is to use memory mapped files to store data (aka global memory). I need this stuff to "talk" to a service in my program. The only limitation (but because of windows) is that if you need this to run in a non-admin account, you need to first use IPCSendString so the file mapping is created before you read it and also use IPCInit() at first. This will allow the file mappings to be accessed from a restricted program too. I will make this better, I am just starting to work at it these days.

Posted: Tue Jan 29, 2008 1:45 pm
by pdwyer
8)

This is pretty cool.

Posted: Tue Jan 29, 2008 1:56 pm
by Kwai chang caine
Great !!! 8)
It's works fine here with W2000

Thanks for sharing

Posted: Tue Jan 29, 2008 2:09 pm
by pdwyer
Playing with this you need to consider the clean up. When I tried this sending data from one app to another the recieveing app checked it's buffer and the same data was alwyas in there. The workaround was to have the receiver clear it.

Try these two apps, note the receiver app clears the buffer, if you remove that line have a look at what happens. I really like this though

Sender App

Code: Select all

XIncludeFile "IPC.pbi" 

IPCInit() 

OpenConsole()
    Repeat
        PrintN("Type Text To send:")
        SendStr.s = Input()
        IPCSendString("JUST_A_TEST",SendStr)       
    ForEver 
CloseConsole()

Reciever App

Code: Select all

XIncludeFile "IPC.pbi" 

IPCInit() 

OpenConsole()
    PrintN("Waiting to Receive Text...")
    Repeat
        
        rcvd.s = IPCReceiveString("JUST_A_TEST")
        If rcvd <> ""
            PrintN(rcvd)
            rcvd = ""
            IPCSendString("JUST_A_TEST","")  ;clear string from buffer, comment this line to see what I mean
            PrintN("Waiting to Receive Text...")
        
        EndIf
        
        Delay(1)
    ForEver 
CloseConsole()
I swaped the debugger for the consol as it's easier for me I find

Posted: Tue Jan 29, 2008 2:21 pm
by pdwyer
With the security could you have two users communicate? For example, (an idea just popped into my head but I'm about to go to bed so I don't have time to try it now) if you had two users on RDP teminal services sessions could this be used as a chat program? :idea:

I could have this on servers for admins to chat if they bump into eachother on the same box "Oi! Get off, I'm about to reboot!" etc :)

hmm, needs some thought