Simple IPC

Share your advanced PureBasic knowledge/code with the community.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Simple IPC

Post 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
Last edited by Inf0Byt3 on Tue Jan 29, 2008 6:22 pm, edited 2 times in total.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post 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
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Post 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.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

8)

This is pretty cool.
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Great !!! 8)
It's works fine here with W2000

Thanks for sharing
ImageThe happiness is a road...
Not a destination
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post 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
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post 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
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Post Reply