├── .gitignore
├── Client.dpr
├── Client.dproj
├── DelphiIPC.groupproj
├── IPC.Demo.Types.pas
├── IPC.pas
├── README.md
├── Server.dpr
├── Server.dproj
├── Unit_Client.dfm
├── Unit_Client.pas
├── Unit_Server.dfm
└── Unit_Server.pas
/.gitignore:
--------------------------------------------------------------------------------
1 | # Uncomment these types if you want even more clean repository. But be careful.
2 | # It can make harm to an existing project source. Read explanations below.
3 | #
4 | # Resource files are binaries containing manifest, project icon and version info.
5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
6 | #*.res
7 | #
8 | # Type library file (binary). In old Delphi versions it should be stored.
9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
10 | #*.tlb
11 | #
12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
13 | # Uncomment this if you are not using diagrams or use newer Delphi version.
14 | #*.ddp
15 | #
16 | # Visual LiveBindings file. Added in Delphi XE2.
17 | # Uncomment this if you are not using LiveBindings Designer.
18 | #*.vlb
19 | #
20 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
21 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
22 | #*.deployproj
23 | #
24 | # C++ object files produced when C/C++ Output file generation is configured.
25 | # Uncomment this if you are not using external objects (zlib library for example).
26 | #*.obj
27 | #
28 |
29 | # Delphi compiler-generated binaries (safe to delete)
30 | *.exe
31 | *.dll
32 | *.bpl
33 | *.bpi
34 | *.dcp
35 | *.so
36 | *.apk
37 | *.drc
38 | *.map
39 | *.dres
40 | *.rsm
41 | *.tds
42 | *.dcu
43 | *.lib
44 | *.a
45 | *.o
46 | *.ocx
47 |
48 | # Delphi autogenerated files (duplicated info)
49 | *.cfg
50 | *.hpp
51 | *Resource.rc
52 |
53 | # Delphi local files (user-specific info)
54 | *.local
55 | *.identcache
56 | *.projdata
57 | *.tvsconfig
58 | *.dsk
59 |
60 | # Delphi history and backups
61 | __history/
62 | __recovery/
63 | *.~*
64 |
65 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
66 | *.stat
67 |
--------------------------------------------------------------------------------
/Client.dpr:
--------------------------------------------------------------------------------
1 | program Client;
2 |
3 | uses
4 | Forms,
5 | Unit_Client in 'Unit_Client.pas' {Form1},
6 | IPC.Demo.Types in 'IPC.Demo.Types.pas';
7 |
8 | {$R *.res}
9 |
10 | begin
11 | ReportMemoryLeaksOnShutdown := True;
12 | Application.Initialize;
13 | Application.MainFormOnTaskbar := True;
14 | Application.CreateForm(TForm1, Form1);
15 | Application.Run;
16 | end.
17 |
18 |
--------------------------------------------------------------------------------
/Client.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {A38310C9-430B-4F00-AA4B-9620CE32B3B9}
4 | Client.dpr
5 | True
6 | Debug
7 | 1
8 | Application
9 | VCL
10 | 18.6
11 | Win32
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Base
29 | true
30 |
31 |
32 | true
33 | Cfg_1
34 | true
35 | true
36 |
37 |
38 | true
39 | Base
40 | true
41 |
42 |
43 | true
44 | Cfg_2
45 | true
46 | true
47 |
48 |
49 | false
50 | false
51 | false
52 | false
53 | false
54 | 00400000
55 | Client
56 | Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
57 | 1033
58 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=
59 |
60 |
61 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
62 | Debug
63 | true
64 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
65 | $(BDS)\bin\default_app.manifest
66 | $(BDS)\bin\delphi_PROJECTICON.ico
67 | true
68 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
69 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
70 |
71 |
72 | Client_Icon.ico
73 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
74 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
75 |
76 |
77 | RELEASE;$(DCC_Define)
78 | 0
79 | false
80 | 0
81 |
82 |
83 | true
84 | PerMonitorV2
85 | true
86 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
87 |
88 |
89 | DEBUG;$(DCC_Define)
90 | false
91 | true
92 |
93 |
94 | true
95 | PerMonitorV2
96 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
97 | true
98 |
99 |
100 |
101 | MainSource
102 |
103 |
104 |
105 |
106 |
107 |
108 | Cfg_2
109 | Base
110 |
111 |
112 | Base
113 |
114 |
115 | Cfg_1
116 | Base
117 |
118 |
119 |
120 | Delphi.Personality.12
121 |
122 |
123 |
124 |
125 | Client.dpr
126 |
127 |
128 | Microsoft Office 2000 Sample Automation Server Wrapper Components
129 | Microsoft Office XP Sample Automation Server Wrapper Components
130 |
131 |
132 |
133 | True
134 | False
135 |
136 |
137 |
138 |
139 | Client.exe
140 | true
141 |
142 |
143 |
144 |
145 | 1
146 |
147 |
148 | Contents\MacOS
149 | 1
150 |
151 |
152 | 0
153 |
154 |
155 |
156 |
157 | classes
158 | 1
159 |
160 |
161 |
162 |
163 | res\xml
164 | 1
165 |
166 |
167 |
168 |
169 | library\lib\armeabi-v7a
170 | 1
171 |
172 |
173 |
174 |
175 | library\lib\armeabi
176 | 1
177 |
178 |
179 |
180 |
181 | library\lib\mips
182 | 1
183 |
184 |
185 |
186 |
187 | library\lib\armeabi-v7a
188 | 1
189 |
190 |
191 |
192 |
193 | res\drawable
194 | 1
195 |
196 |
197 |
198 |
199 | res\values
200 | 1
201 |
202 |
203 |
204 |
205 | res\values-v21
206 | 1
207 |
208 |
209 |
210 |
211 | res\drawable
212 | 1
213 |
214 |
215 |
216 |
217 | res\drawable-xxhdpi
218 | 1
219 |
220 |
221 |
222 |
223 | res\drawable-ldpi
224 | 1
225 |
226 |
227 |
228 |
229 | res\drawable-mdpi
230 | 1
231 |
232 |
233 |
234 |
235 | res\drawable-hdpi
236 | 1
237 |
238 |
239 |
240 |
241 | res\drawable-xhdpi
242 | 1
243 |
244 |
245 |
246 |
247 | res\drawable-small
248 | 1
249 |
250 |
251 |
252 |
253 | res\drawable-normal
254 | 1
255 |
256 |
257 |
258 |
259 | res\drawable-large
260 | 1
261 |
262 |
263 |
264 |
265 | res\drawable-xlarge
266 | 1
267 |
268 |
269 |
270 |
271 | 1
272 |
273 |
274 | Contents\MacOS
275 | 1
276 |
277 |
278 | 0
279 |
280 |
281 |
282 |
283 | Contents\MacOS
284 | 1
285 | .framework
286 |
287 |
288 | Contents\MacOS
289 | 1
290 | .framework
291 |
292 |
293 | 0
294 |
295 |
296 |
297 |
298 | 1
299 | .dylib
300 |
301 |
302 | 1
303 | .dylib
304 |
305 |
306 | 1
307 | .dylib
308 |
309 |
310 | Contents\MacOS
311 | 1
312 | .dylib
313 |
314 |
315 | Contents\MacOS
316 | 1
317 | .dylib
318 |
319 |
320 | 0
321 | .dll;.bpl
322 |
323 |
324 |
325 |
326 | 1
327 | .dylib
328 |
329 |
330 | 1
331 | .dylib
332 |
333 |
334 | 1
335 | .dylib
336 |
337 |
338 | Contents\MacOS
339 | 1
340 | .dylib
341 |
342 |
343 | Contents\MacOS
344 | 1
345 | .dylib
346 |
347 |
348 | 0
349 | .bpl
350 |
351 |
352 |
353 |
354 | 0
355 |
356 |
357 | 0
358 |
359 |
360 | 0
361 |
362 |
363 | 0
364 |
365 |
366 | Contents\Resources\StartUp\
367 | 0
368 |
369 |
370 | Contents\Resources\StartUp\
371 | 0
372 |
373 |
374 | 0
375 |
376 |
377 |
378 |
379 | 1
380 |
381 |
382 | 1
383 |
384 |
385 | 1
386 |
387 |
388 |
389 |
390 | 1
391 |
392 |
393 | 1
394 |
395 |
396 | 1
397 |
398 |
399 |
400 |
401 | 1
402 |
403 |
404 | 1
405 |
406 |
407 | 1
408 |
409 |
410 |
411 |
412 | 1
413 |
414 |
415 | 1
416 |
417 |
418 | 1
419 |
420 |
421 |
422 |
423 | 1
424 |
425 |
426 | 1
427 |
428 |
429 | 1
430 |
431 |
432 |
433 |
434 | 1
435 |
436 |
437 | 1
438 |
439 |
440 | 1
441 |
442 |
443 |
444 |
445 | 1
446 |
447 |
448 | 1
449 |
450 |
451 | 1
452 |
453 |
454 |
455 |
456 | 1
457 |
458 |
459 |
460 |
461 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
462 | 1
463 |
464 |
465 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
466 | 1
467 |
468 |
469 |
470 |
471 | 1
472 |
473 |
474 | 1
475 |
476 |
477 |
478 |
479 | ..\
480 | 1
481 |
482 |
483 | ..\
484 | 1
485 |
486 |
487 |
488 |
489 | 1
490 |
491 |
492 | 1
493 |
494 |
495 | 1
496 |
497 |
498 |
499 |
500 | 1
501 |
502 |
503 | 1
504 |
505 |
506 | 1
507 |
508 |
509 |
510 |
511 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
512 | 1
513 |
514 |
515 |
516 |
517 | ..\
518 | 1
519 |
520 |
521 | ..\
522 | 1
523 |
524 |
525 |
526 |
527 | Contents
528 | 1
529 |
530 |
531 | Contents
532 | 1
533 |
534 |
535 |
536 |
537 | Contents\Resources
538 | 1
539 |
540 |
541 | Contents\Resources
542 | 1
543 |
544 |
545 |
546 |
547 | library\lib\armeabi-v7a
548 | 1
549 |
550 |
551 | 1
552 |
553 |
554 | 1
555 |
556 |
557 | 1
558 |
559 |
560 | 1
561 |
562 |
563 | Contents\MacOS
564 | 1
565 |
566 |
567 | Contents\MacOS
568 | 1
569 |
570 |
571 | 0
572 |
573 |
574 |
575 |
576 | 1
577 |
578 |
579 | 1
580 |
581 |
582 |
583 |
584 | Assets
585 | 1
586 |
587 |
588 | Assets
589 | 1
590 |
591 |
592 |
593 |
594 | Assets
595 | 1
596 |
597 |
598 | Assets
599 | 1
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 | 12
614 |
615 |
616 |
617 |
618 |
619 |
--------------------------------------------------------------------------------
/DelphiIPC.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {73B6280D-7FC6-4D9F-AEB2-D80998DE0418}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Default.Personality.12
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/IPC.Demo.Types.pas:
--------------------------------------------------------------------------------
1 | unit IPC.Demo.Types;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows;
7 |
8 | const
9 | MAX_LENGTH = 1024;
10 |
11 | type
12 | TData = packed record
13 | ProcessId: DWORD;
14 | Text: array[0..MAX_LENGTH] of WideChar;
15 | procedure SetText(const AValue: string);
16 | end;
17 |
18 | type
19 | TResponseData = packed record
20 | Text: array[0..MAX_LENGTH] of WideChar;
21 | end;
22 |
23 | type
24 | PResponseData = ^TResponseData;
25 |
26 | implementation
27 |
28 | { TData }
29 |
30 | procedure TData.SetText(const AValue: string);
31 | begin
32 | lstrcpynW(Text, PWideChar(AValue), MAX_LENGTH);
33 | end;
34 |
35 | end.
36 |
37 |
--------------------------------------------------------------------------------
/IPC.pas:
--------------------------------------------------------------------------------
1 | unit IPC;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows,
7 | System.SysUtils,
8 | System.Classes;
9 |
10 | type
11 | TServerRecieveIpcDataEvent = procedure(Sender: TObject; var ClientName:
12 | WideString; var ClientWaitingForResponse: Boolean; var Data: Pointer) of object;
13 |
14 | TClientRecieveResponseIpcDataEvent = procedure(Sender: TObject; var Data: Pointer) of object;
15 |
16 | TIPCServer = class;
17 |
18 | TIPCClient = class;
19 |
20 | TServerThread = class;
21 |
22 | TIPCServer = class(TComponent)
23 | private
24 | FServerHandle: THandle;
25 | FServerThread: TServerThread;
26 | FOnRecieveIpcData: TServerRecieveIpcDataEvent;
27 | FServerThreadEnabled: Boolean;
28 | FLastError: Integer;
29 | protected
30 | function ReadData(var ClientName: WideString; var ClientWaitingForResponse:
31 | Boolean; var Data: Pointer): Boolean;
32 | public
33 | constructor Create(AOwner: TComponent); override;
34 | destructor Destroy; override;
35 | function CreateServer(ServerName: WideString): Boolean;
36 | function FreeServer: Boolean;
37 | function SendIpcData(ClientName: WideString; Data: Pointer; DataSize: DWORD): Boolean;
38 | public
39 | property OnRecieveIpcData: TServerRecieveIpcDataEvent read FOnRecieveIpcData
40 | write FOnRecieveIpcData;
41 | property LastError: Integer read FLastError;
42 | end;
43 |
44 | TServerThread = class(TThread)
45 | private
46 | FThreadOwner: TIPCServer;
47 | protected
48 | procedure DoReadData;
49 | procedure Execute; override;
50 | public
51 | constructor Create(AThreadOwner: TIPCServer);
52 | destructor Destroy; override;
53 | end;
54 |
55 | TIPCClient = class(TComponent)
56 | private
57 | FClientName: WideString;
58 | FResponseServerHandle: THandle;
59 | FOnRecieveIpcData: TClientRecieveResponseIpcDataEvent;
60 | FLastError: Integer;
61 | protected
62 | function ReadData(ServerHandle: THandle; var ClientName: WideString; var
63 | Data: Pointer): Boolean;
64 | public
65 | constructor Create(AOwner: TComponent); override;
66 | destructor Destroy; override;
67 | function CreateClient(ClientName: WideString): Boolean;
68 | function FreeClient: Boolean;
69 | function Send(ServerName: WideString; Data: T; WaitForResponse: Boolean;
70 | ResponseTimeout: ULONG; var ResponseData: Pointer): Boolean;
71 | public
72 | property OnRecieveResponseIpcData: TClientRecieveResponseIpcDataEvent read
73 | FOnRecieveIpcData write FOnRecieveIpcData;
74 | property LastError: Integer read FLastError;
75 | end;
76 |
77 | type
78 | TClientNameData = packed record
79 | ClientName: array[0..255] of WideChar;
80 | ClientWaitingForResponse: Boolean;
81 | end;
82 |
83 | implementation
84 |
85 | type
86 | TConvertStringSecurityDescriptorToSecurityDescriptorW = function(StringSecurityDescriptor:
87 | LPCWSTR; StringSDRevision: DWORD; var SecurityDescriptor: Pointer;
88 | SecurityDescriptorSize: PULONG): BOOL; stdcall;
89 |
90 | var
91 | OSVersion: DWORD;
92 | ConvertStringSecurityDescriptorToSecurityDescriptorW:
93 | TConvertStringSecurityDescriptorToSecurityDescriptorW;
94 |
95 | function GetOSVersion: DWORD;
96 | begin
97 | Result := (TOSVersion.Major.ToString + TOSVersion.Minor.ToString).ToInteger;
98 | end;
99 |
100 | constructor TIPCServer.Create(AOwner: TComponent);
101 | begin
102 | inherited Create(AOwner);
103 | FServerHandle := 0;
104 | end;
105 |
106 | destructor TIPCServer.Destroy;
107 | begin
108 | FreeServer;
109 | inherited;
110 | end;
111 |
112 | const
113 | LOW_INTEGRITY_SDDL_SACL = 'D:' + '(A;OICI;GRGW;;;AU)' + '(A;OICI;GRGW;;;BA)' +
114 | '(A;OICI;GRGW;;;AN)' + '(A;OICI;GRGW;;;BG)' + 'S:(ML;;NW;;;LW)';
115 | SDDL_REVISION_1 = 1;
116 |
117 | function TIPCServer.CreateServer(ServerName: WideString): Boolean;
118 | var
119 | SecurityAttributes: TSecurityAttributes;
120 | SecurityDescriptor: TSecurityDescriptor;
121 | SecurityDescriptor_V: PSECURITY_DESCRIPTOR;
122 | BufferSize: DWORD;
123 | begin
124 | Result := False;
125 | try
126 | if GetMailslotInfo(FServerHandle, nil, BufferSize, nil, nil) then
127 | begin
128 | FLastError := ERROR_ALREADY_EXISTS;
129 | Exit;
130 | end;
131 |
132 | if OSVersion >= 60 then
133 | begin
134 | FillChar(SecurityDescriptor_V, SizeOf(PSECURITY_DESCRIPTOR), 0);
135 |
136 | if not ConvertStringSecurityDescriptorToSecurityDescriptorW(LOW_INTEGRITY_SDDL_SACL,
137 | SDDL_REVISION_1, SecurityDescriptor_V, nil) then
138 | begin
139 | FLastError := GetLastError;
140 | Exit;
141 | end;
142 |
143 | SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
144 | SecurityAttributes.lpSecurityDescriptor := SecurityDescriptor_V;
145 | SecurityAttributes.bInheritHandle := True;
146 |
147 | end
148 | else if (OSVersion >= 50) and (OSVersion < 60) then
149 | begin
150 | FillChar(SecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH, 0);
151 | if InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
152 | begin
153 | if SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False) then
154 | begin
155 | SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
156 | SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;
157 | SecurityAttributes.bInheritHandle := True;
158 | end;
159 | end;
160 | end;
161 |
162 | FServerHandle := CreateMailslotW(PWideChar('\\.\mailslot\' + ServerName), 0,
163 | 0, @SecurityAttributes);
164 |
165 | if FServerHandle = INVALID_HANDLE_VALUE then
166 | begin
167 | FLastError := GetLastError;
168 | Exit;
169 | end;
170 |
171 | if (FServerThreadEnabled = False) then
172 | begin
173 | FServerThread := TServerThread.Create(Self);
174 | FServerThreadEnabled := True;
175 | end;
176 |
177 | Result := True;
178 | FLastError := ERROR_SUCCESS;
179 | except
180 | end;
181 | end;
182 |
183 | function TIPCServer.FreeServer: Boolean;
184 | begin
185 | Result := False;
186 | try
187 | if FServerThreadEnabled = True then
188 | begin
189 | FServerThread.Terminate;
190 | end;
191 |
192 | if FServerHandle <> 0 then
193 | begin
194 | CloseHandle(FServerHandle);
195 | FServerHandle := 0;
196 | end;
197 |
198 | FLastError := ERROR_SUCCESS;
199 | Result := True;
200 | except
201 | end;
202 | end;
203 |
204 | function TIPCServer.ReadData(var ClientName: WideString; var
205 | ClientWaitingForResponse: Boolean; var Data: Pointer): Boolean;
206 | var
207 | BufferSize, NumberOfBytesWritten: DWORD;
208 | MemoryStream: TMemoryStream;
209 | ClientNameData: TClientNameData;
210 | DataBuffer, ClientDataBuffer: PVOID;
211 | ReadStatus: Boolean;
212 | begin
213 | Result := False;
214 | try
215 | if GetMailslotInfo(FServerHandle, nil, BufferSize, nil, nil) then
216 | begin
217 | if BufferSize <> MAILSLOT_NO_MESSAGE then
218 | begin
219 | GetMem(DataBuffer, BufferSize);
220 | GetMem(ClientDataBuffer, BufferSize);
221 | GetMem(Data, BufferSize);
222 | try
223 | if (DataBuffer <> nil) and (ClientDataBuffer <> nil) and (Data <> nil) then
224 | begin
225 | ReadStatus := ReadFile(FServerHandle, DataBuffer^, BufferSize,
226 | NumberOfBytesWritten, nil);
227 | if ReadStatus then
228 | begin
229 | MemoryStream := TMemoryStream.Create;
230 | try
231 | MemoryStream.Write(DataBuffer^, BufferSize);
232 | MemoryStream.Position := 0;
233 | MemoryStream.Read(ClientDataBuffer^, BufferSize - SizeOf(TClientNameData));
234 | CopyMemory(Data, ClientDataBuffer, BufferSize - SizeOf(TClientNameData));
235 | MemoryStream.Position := BufferSize - SizeOf(TClientNameData);
236 | MemoryStream.Read(ClientNameData, SizeOf(TClientNameData));
237 | ClientName := WideString(ClientNameData.ClientName);
238 | ClientWaitingForResponse := ClientNameData.ClientWaitingForResponse;
239 | finally
240 | MemoryStream.Free;
241 | end;
242 | Result := True;
243 | end;
244 | end;
245 | finally
246 | FreeMem(Data);
247 | FreeMem(ClientDataBuffer);
248 | FreeMem(DataBuffer);
249 | end;
250 | end;
251 | end;
252 | except
253 | end;
254 | end;
255 |
256 | function TIPCServer.SendIpcData(ClientName: WideString; Data: Pointer; DataSize: DWORD): Boolean;
257 | var
258 | MemoryStream: TMemoryStream;
259 | NumberOfBytesWritten: DWORD;
260 | ClientData: TClientNameData;
261 | Buffer: Pointer;
262 | ServerHandle: THandle;
263 | begin
264 | Result := False;
265 | try
266 | ServerHandle := CreateFileW(PWideChar('\\.\mailslot\' + ClientName),
267 | GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
268 | if ServerHandle = INVALID_HANDLE_VALUE then
269 | begin
270 | FLastError := GetLastError;
271 | Exit;
272 | end;
273 | try
274 | lstrcpynW(ClientData.ClientName, PWideChar(ClientName), 255);
275 | MemoryStream := TMemoryStream.Create;
276 | try
277 | MemoryStream.Write(Data^, DataSize);
278 | MemoryStream.Write(ClientData, SizeOf(TClientNameData));
279 | MemoryStream.Position := 0;
280 | GetMem(Buffer, MemoryStream.Size);
281 | try
282 | MemoryStream.Read(Buffer^, MemoryStream.Size);
283 | if WriteFile(ServerHandle, Buffer^, MemoryStream.Size, NumberOfBytesWritten, nil) then
284 | begin
285 | FLastError := ERROR_SUCCESS;
286 | Result := True;
287 | end
288 | else
289 | FLastError := GetLastError;
290 | finally
291 | FreeMem(Buffer);
292 | end;
293 | finally
294 | MemoryStream.Free;
295 | end;
296 | finally
297 | CloseHandle(ServerHandle);
298 | end;
299 | except
300 | end;
301 | end;
302 |
303 | procedure TServerThread.DoReadData;
304 | var
305 | Data: Pointer;
306 | ClientName: WideString;
307 | ClientWaitResponse: Boolean;
308 | begin
309 | try
310 | Data := nil;
311 | if FThreadOwner.ReadData(ClientName, ClientWaitResponse, Data) then
312 | begin
313 | if Data <> nil then
314 | begin
315 | if Assigned(FThreadOwner.FOnRecieveIpcData) then
316 | FThreadOwner.FOnRecieveIpcData(Self, ClientName, ClientWaitResponse, Data);
317 | end;
318 | end;
319 | except
320 | end;
321 | end;
322 |
323 | procedure TServerThread.Execute;
324 | begin
325 | while not Terminated do
326 | begin
327 | Sleep(10);
328 | SYNCHRONIZE(DoReadData);
329 | end;
330 | FThreadOwner.FServerThreadEnabled := False;
331 | end;
332 |
333 | constructor TServerThread.Create(AThreadOwner: TIPCServer);
334 | begin
335 | inherited Create(False);
336 | FThreadOwner := AThreadOwner;
337 | FreeOnTerminate := True;
338 | case GetThreadPriority(GetCurrentThread) of
339 | THREAD_PRIORITY_ABOVE_NORMAL:
340 | Priority := tpHigher;
341 | THREAD_PRIORITY_BELOW_NORMAL:
342 | Priority := tpLower;
343 | THREAD_PRIORITY_HIGHEST:
344 | Priority := tpHighest;
345 | THREAD_PRIORITY_IDLE:
346 | Priority := tpIdle;
347 | THREAD_PRIORITY_LOWEST:
348 | Priority := tpLowest;
349 | THREAD_PRIORITY_NORMAL:
350 | Priority := tpNormal;
351 | THREAD_PRIORITY_TIME_CRITICAL:
352 | Priority := tpTimeCritical;
353 | end;
354 | end;
355 |
356 | destructor TServerThread.Destroy;
357 | begin
358 | inherited;
359 | end;
360 |
361 | // Client
362 | constructor TIPCClient.Create(AOwner: TComponent);
363 | begin
364 | inherited Create(AOwner);
365 | FResponseServerHandle := 0;
366 | end;
367 |
368 | destructor TIPCClient.Destroy;
369 | begin
370 | FreeClient;
371 | inherited;
372 | end;
373 |
374 | function TIPCClient.CreateClient(ClientName: WideString): Boolean;
375 | var
376 | SecurityAttributes: TSecurityAttributes;
377 | SecurityDescriptor: TSecurityDescriptor;
378 | SecurityDescriptor_V: PSECURITY_DESCRIPTOR;
379 | BufferSize: DWORD;
380 | begin
381 | Result := False;
382 | try
383 | if GetMailslotInfo(FResponseServerHandle, nil, BufferSize, nil, nil) then
384 | begin
385 | FLastError := ERROR_ALREADY_EXISTS;
386 | Exit;
387 | end;
388 |
389 | if OSVersion >= 60 then
390 | begin
391 | FillChar(SecurityDescriptor_V, SizeOf(PSECURITY_DESCRIPTOR), 0);
392 |
393 | if not ConvertStringSecurityDescriptorToSecurityDescriptorW(LOW_INTEGRITY_SDDL_SACL,
394 | SDDL_REVISION_1, SecurityDescriptor_V, nil) then
395 | begin
396 | FLastError := GetLastError;
397 | Exit;
398 | end;
399 |
400 | SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
401 | SecurityAttributes.lpSecurityDescriptor := SecurityDescriptor_V;
402 | SecurityAttributes.bInheritHandle := True;
403 | end
404 | else if (OSVersion >= 50) and (OSVersion < 60) then
405 | begin
406 | FillChar(SecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH, 0);
407 | if InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
408 | begin
409 | if SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False) then
410 | begin
411 | SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
412 | SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;
413 | SecurityAttributes.bInheritHandle := True;
414 | end;
415 | end;
416 | end;
417 |
418 | FResponseServerHandle := CreateMailslotW(PWideChar('\\.\mailslot\' +
419 | ClientName), 0, 0, @SecurityAttributes);
420 |
421 | if FResponseServerHandle = INVALID_HANDLE_VALUE then
422 | begin
423 | FLastError := GetLastError;
424 | Exit;
425 | end;
426 |
427 | Result := True;
428 | FClientName := ClientName;
429 | FLastError := ERROR_SUCCESS;
430 | except
431 | end;
432 | end;
433 |
434 | function TIPCClient.FreeClient: Boolean;
435 | begin
436 | Result := False;
437 | try
438 | if FResponseServerHandle <> 0 then
439 | begin
440 | CloseHandle(FResponseServerHandle);
441 | FResponseServerHandle := 0;
442 | end;
443 | FLastError := ERROR_SUCCESS;
444 | Result := True;
445 | except
446 | end;
447 | end;
448 |
449 | function TIPCClient.ReadData(ServerHandle: THandle; var ClientName: WideString;
450 | var Data: Pointer): Boolean;
451 | var
452 | BufferSize, NumberOfBytesWritten: DWORD;
453 | MemoryStream: TMemoryStream;
454 | ClientNameData: TClientNameData;
455 | DataBuffer, ClientDataBuffer: Pointer;
456 | begin
457 | Result := False;
458 | try
459 | if GetMailslotInfo(ServerHandle, nil, BufferSize, nil, nil) then
460 | begin
461 | if BufferSize <> MAILSLOT_NO_MESSAGE then
462 | begin
463 | GetMem(DataBuffer, BufferSize);
464 | GetMem(ClientDataBuffer, BufferSize);
465 | GetMem(Data, BufferSize);
466 |
467 | try
468 | if (DataBuffer <> nil) and (ClientDataBuffer <> nil) and (Data <> nil) then
469 | begin
470 | if ReadFile(ServerHandle, DataBuffer^, BufferSize, NumberOfBytesWritten, nil) then
471 | begin
472 | MemoryStream := TMemoryStream.Create;
473 | try
474 | MemoryStream.Write(DataBuffer^, BufferSize);
475 |
476 | MemoryStream.Position := 0;
477 |
478 | MemoryStream.Read(ClientDataBuffer^, BufferSize - SizeOf(TClientNameData));
479 |
480 | CopyMemory(Data, ClientDataBuffer, BufferSize - SizeOf(TClientNameData));
481 |
482 | MemoryStream.Position := BufferSize - SizeOf(TClientNameData);
483 |
484 | MemoryStream.Read(ClientNameData, SizeOf(TClientNameData));
485 |
486 | ClientName := WideString(ClientNameData.ClientName);
487 | finally
488 | MemoryStream.Free;
489 | end;
490 | Result := True;
491 | end;
492 | end;
493 | finally
494 | FreeMem(Data);
495 | FreeMem(ClientDataBuffer);
496 | FreeMem(DataBuffer);
497 | end;
498 | end;
499 | end;
500 | except
501 | end;
502 | end;
503 |
504 | function TIPCClient.Send(ServerName: WideString; Data: T; WaitForResponse:
505 | Boolean; ResponseTimeout: ULONG; var ResponseData: Pointer): Boolean;
506 | var
507 | MemoryStream: TMemoryStream;
508 | i, NumberOfBytesWritten: DWORD;
509 | ClientNameData: TClientNameData;
510 | Buffer: Pointer;
511 | ServerHandle: THandle;
512 | ClientName: WideString;
513 | BufferSize: DWORD;
514 | begin
515 | Result := False;
516 | try
517 | ServerHandle := CreateFileW(PWideChar('\\.\mailslot\' + ServerName),
518 | GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
519 | if ServerHandle = INVALID_HANDLE_VALUE then
520 | begin
521 | FLastError := GetLastError;
522 | Exit;
523 | end;
524 |
525 | try
526 | lstrcpynW(ClientNameData.ClientName, PWideChar(FClientName), 255);
527 | ClientNameData.ClientWaitingForResponse := WaitForResponse;
528 |
529 | MemoryStream := TMemoryStream.Create;
530 | try
531 | MemoryStream.Write(Data, SizeOf(Data) {DataSize});
532 | MemoryStream.Write(ClientNameData, SizeOf(TClientNameData));
533 | MemoryStream.Position := 0;
534 |
535 | GetMem(Buffer, MemoryStream.Size);
536 | try
537 | MemoryStream.Read(Buffer^, MemoryStream.Size);
538 | if not WriteFile(ServerHandle, Buffer^, MemoryStream.Size, NumberOfBytesWritten, nil) then
539 | begin
540 | FLastError := GetLastError;
541 | Exit;
542 | end;
543 | finally
544 | FreeMem(Buffer);
545 | end;
546 | finally
547 | MemoryStream.Free;
548 | end;
549 | finally
550 | CloseHandle(ServerHandle);
551 | end;
552 |
553 | FLastError := ERROR_SUCCESS;
554 | Result := True;
555 |
556 | if (WaitForResponse = True) and (ResponseTimeout > 0) then
557 | begin
558 |
559 | try
560 | i := 0;
561 | while True do
562 | begin
563 |
564 | if ReadData(FResponseServerHandle, ClientName, ResponseData) then
565 | begin
566 | if ResponseData <> nil then
567 | begin
568 | if ClientName = FClientName then
569 | begin
570 | if Assigned(FOnRecieveIpcData) then
571 | FOnRecieveIpcData(Self, ResponseData);
572 | Exit;
573 | end;
574 | end;
575 | end;
576 |
577 | Inc(i);
578 | Sleep(1);
579 | if i >= ResponseTimeout then
580 | begin
581 | Exit;
582 | end;
583 | end;
584 | except
585 | Exit;
586 | end;
587 | end;
588 | except
589 | end;
590 | end;
591 |
592 | procedure _Initialize;
593 | var
594 | hLibrary: HMODULE;
595 | begin
596 | OSVersion := GetOSVersion;
597 | hLibrary := LoadLibrary('advapi32.dll');
598 | if (hLibrary <> 0) and (OSVersion >= 60) then
599 | begin
600 | @ConvertStringSecurityDescriptorToSecurityDescriptorW := GetProcAddress(hLibrary,
601 | 'ConvertStringSecurityDescriptorToSecurityDescriptorW');
602 | end;
603 | end;
604 |
605 | initialization
606 | _Initialize;
607 |
608 | end.
609 |
610 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Delphi-Inter-Process-Communication
2 | Автор Зорков Игорь.
3 |
--------------------------------------------------------------------------------
/Server.dpr:
--------------------------------------------------------------------------------
1 | program Server;
2 |
3 | uses
4 | Vcl.Forms,
5 | Unit_Server in 'Unit_Server.pas' {Form1},
6 | IPC.Demo.Types in 'IPC.Demo.Types.pas';
7 |
8 | {$R *.res}
9 |
10 | begin
11 | ReportMemoryLeaksOnShutdown := True;
12 | Application.Initialize;
13 | Application.MainFormOnTaskbar := True;
14 | Application.CreateForm(TForm1, Form1);
15 | Application.Run;
16 | end.
17 |
18 |
--------------------------------------------------------------------------------
/Server.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {CF6DECE9-D6C8-4631-B15A-A1AEE4B5243D}
4 | Server.dpr
5 | True
6 | Debug
7 | 1
8 | Application
9 | VCL
10 | 18.6
11 | Win32
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Base
29 | true
30 |
31 |
32 | true
33 | Cfg_1
34 | true
35 | true
36 |
37 |
38 | true
39 | Base
40 | true
41 |
42 |
43 | true
44 | Cfg_2
45 | true
46 | true
47 |
48 |
49 | false
50 | false
51 | false
52 | false
53 | false
54 | 00400000
55 | Server
56 | Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
57 | 1033
58 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=
59 |
60 |
61 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
62 | Debug
63 | true
64 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
65 | $(BDS)\bin\default_app.manifest
66 | $(BDS)\bin\delphi_PROJECTICON.ico
67 | true
68 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
69 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
70 |
71 |
72 | $(BDS)\bin\default_app.manifest
73 | Server_Icon.ico
74 | true
75 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
76 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
77 |
78 |
79 | RELEASE;$(DCC_Define)
80 | 0
81 | false
82 | 0
83 |
84 |
85 | true
86 | PerMonitorV2
87 | true
88 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
89 |
90 |
91 | DEBUG;$(DCC_Define)
92 | false
93 | true
94 |
95 |
96 | true
97 | PerMonitorV2
98 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
99 | true
100 |
101 |
102 |
103 | MainSource
104 |
105 |
106 |
107 |
108 |
109 |
110 | Cfg_2
111 | Base
112 |
113 |
114 | Base
115 |
116 |
117 | Cfg_1
118 | Base
119 |
120 |
121 |
122 | Delphi.Personality.12
123 |
124 |
125 |
126 |
127 | Server.dpr
128 |
129 |
130 | Microsoft Office 2000 Sample Automation Server Wrapper Components
131 | Microsoft Office XP Sample Automation Server Wrapper Components
132 |
133 |
134 |
135 | True
136 | False
137 |
138 |
139 |
140 |
141 | Server.exe
142 | true
143 |
144 |
145 |
146 |
147 | 1
148 |
149 |
150 | Contents\MacOS
151 | 1
152 |
153 |
154 | 0
155 |
156 |
157 |
158 |
159 | classes
160 | 1
161 |
162 |
163 |
164 |
165 | res\xml
166 | 1
167 |
168 |
169 |
170 |
171 | library\lib\armeabi-v7a
172 | 1
173 |
174 |
175 |
176 |
177 | library\lib\armeabi
178 | 1
179 |
180 |
181 |
182 |
183 | library\lib\mips
184 | 1
185 |
186 |
187 |
188 |
189 | library\lib\armeabi-v7a
190 | 1
191 |
192 |
193 |
194 |
195 | res\drawable
196 | 1
197 |
198 |
199 |
200 |
201 | res\values
202 | 1
203 |
204 |
205 |
206 |
207 | res\values-v21
208 | 1
209 |
210 |
211 |
212 |
213 | res\drawable
214 | 1
215 |
216 |
217 |
218 |
219 | res\drawable-xxhdpi
220 | 1
221 |
222 |
223 |
224 |
225 | res\drawable-ldpi
226 | 1
227 |
228 |
229 |
230 |
231 | res\drawable-mdpi
232 | 1
233 |
234 |
235 |
236 |
237 | res\drawable-hdpi
238 | 1
239 |
240 |
241 |
242 |
243 | res\drawable-xhdpi
244 | 1
245 |
246 |
247 |
248 |
249 | res\drawable-small
250 | 1
251 |
252 |
253 |
254 |
255 | res\drawable-normal
256 | 1
257 |
258 |
259 |
260 |
261 | res\drawable-large
262 | 1
263 |
264 |
265 |
266 |
267 | res\drawable-xlarge
268 | 1
269 |
270 |
271 |
272 |
273 | 1
274 |
275 |
276 | Contents\MacOS
277 | 1
278 |
279 |
280 | 0
281 |
282 |
283 |
284 |
285 | Contents\MacOS
286 | 1
287 | .framework
288 |
289 |
290 | Contents\MacOS
291 | 1
292 | .framework
293 |
294 |
295 | 0
296 |
297 |
298 |
299 |
300 | 1
301 | .dylib
302 |
303 |
304 | 1
305 | .dylib
306 |
307 |
308 | 1
309 | .dylib
310 |
311 |
312 | Contents\MacOS
313 | 1
314 | .dylib
315 |
316 |
317 | Contents\MacOS
318 | 1
319 | .dylib
320 |
321 |
322 | 0
323 | .dll;.bpl
324 |
325 |
326 |
327 |
328 | 1
329 | .dylib
330 |
331 |
332 | 1
333 | .dylib
334 |
335 |
336 | 1
337 | .dylib
338 |
339 |
340 | Contents\MacOS
341 | 1
342 | .dylib
343 |
344 |
345 | Contents\MacOS
346 | 1
347 | .dylib
348 |
349 |
350 | 0
351 | .bpl
352 |
353 |
354 |
355 |
356 | 0
357 |
358 |
359 | 0
360 |
361 |
362 | 0
363 |
364 |
365 | 0
366 |
367 |
368 | Contents\Resources\StartUp\
369 | 0
370 |
371 |
372 | Contents\Resources\StartUp\
373 | 0
374 |
375 |
376 | 0
377 |
378 |
379 |
380 |
381 | 1
382 |
383 |
384 | 1
385 |
386 |
387 | 1
388 |
389 |
390 |
391 |
392 | 1
393 |
394 |
395 | 1
396 |
397 |
398 | 1
399 |
400 |
401 |
402 |
403 | 1
404 |
405 |
406 | 1
407 |
408 |
409 | 1
410 |
411 |
412 |
413 |
414 | 1
415 |
416 |
417 | 1
418 |
419 |
420 | 1
421 |
422 |
423 |
424 |
425 | 1
426 |
427 |
428 | 1
429 |
430 |
431 | 1
432 |
433 |
434 |
435 |
436 | 1
437 |
438 |
439 | 1
440 |
441 |
442 | 1
443 |
444 |
445 |
446 |
447 | 1
448 |
449 |
450 | 1
451 |
452 |
453 | 1
454 |
455 |
456 |
457 |
458 | 1
459 |
460 |
461 |
462 |
463 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
464 | 1
465 |
466 |
467 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
468 | 1
469 |
470 |
471 |
472 |
473 | 1
474 |
475 |
476 | 1
477 |
478 |
479 |
480 |
481 | ..\
482 | 1
483 |
484 |
485 | ..\
486 | 1
487 |
488 |
489 |
490 |
491 | 1
492 |
493 |
494 | 1
495 |
496 |
497 | 1
498 |
499 |
500 |
501 |
502 | 1
503 |
504 |
505 | 1
506 |
507 |
508 | 1
509 |
510 |
511 |
512 |
513 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
514 | 1
515 |
516 |
517 |
518 |
519 | ..\
520 | 1
521 |
522 |
523 | ..\
524 | 1
525 |
526 |
527 |
528 |
529 | Contents
530 | 1
531 |
532 |
533 | Contents
534 | 1
535 |
536 |
537 |
538 |
539 | Contents\Resources
540 | 1
541 |
542 |
543 | Contents\Resources
544 | 1
545 |
546 |
547 |
548 |
549 | library\lib\armeabi-v7a
550 | 1
551 |
552 |
553 | 1
554 |
555 |
556 | 1
557 |
558 |
559 | 1
560 |
561 |
562 | 1
563 |
564 |
565 | Contents\MacOS
566 | 1
567 |
568 |
569 | Contents\MacOS
570 | 1
571 |
572 |
573 | 0
574 |
575 |
576 |
577 |
578 | 1
579 |
580 |
581 | 1
582 |
583 |
584 |
585 |
586 | Assets
587 | 1
588 |
589 |
590 | Assets
591 | 1
592 |
593 |
594 |
595 |
596 | Assets
597 | 1
598 |
599 |
600 | Assets
601 | 1
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 | 12
616 |
617 |
618 |
619 |
620 |
621 |
--------------------------------------------------------------------------------
/Unit_Client.dfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 258
3 | Top = 128
4 | Caption = 'IPC Client'
5 | ClientHeight = 234
6 | ClientWidth = 561
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -14
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | Position = poDesktopCenter
15 | OnCreate = FormCreate
16 | OnDestroy = FormDestroy
17 | DesignSize = (
18 | 561
19 | 234)
20 | PixelsPerInch = 120
21 | TextHeight = 17
22 | object Button1: TButton
23 | Left = 10
24 | Top = 201
25 | Width = 146
26 | Height = 33
27 | Anchors = [akLeft, akBottom]
28 | Caption = 'Send IPC Data'
29 | TabOrder = 1
30 | OnClick = Button1Click
31 | end
32 | object Memo1: TMemo
33 | Left = 10
34 | Top = 10
35 | Width = 548
36 | Height = 178
37 | Anchors = [akLeft, akTop, akRight, akBottom]
38 | ScrollBars = ssVertical
39 | TabOrder = 0
40 | end
41 | object CheckBox1: TCheckBox
42 | Left = 174
43 | Top = 207
44 | Width = 152
45 | Height = 22
46 | Anchors = [akLeft, akBottom]
47 | Caption = 'Wait For Response'
48 | TabOrder = 2
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/Unit_Client.pas:
--------------------------------------------------------------------------------
1 | unit Unit_Client;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows,
7 | Winapi.Messages,
8 | System.SysUtils,
9 | System.Variants,
10 | System.Classes,
11 | Vcl.Graphics,
12 | Vcl.Controls,
13 | Vcl.Forms,
14 | Vcl.Dialogs,
15 | Vcl.StdCtrls,
16 | Vcl.ExtCtrls,
17 | Vcl.ComCtrls,
18 | IPC;
19 |
20 | type
21 | TForm1 = class(TForm)
22 | Button1: TButton;
23 | Memo1: TMemo;
24 | CheckBox1: TCheckBox;
25 | procedure Button1Click(Sender: TObject);
26 | procedure FormCreate(Sender: TObject);
27 | procedure FormDestroy(Sender: TObject);
28 | private
29 | { Private declarations }
30 | FIPCClient: TIPCClient;
31 | public
32 | { Public declarations }
33 | procedure ClientRecieveResponseIpcData(Sender: TObject; var ResponseData: Pointer);
34 | end;
35 |
36 | var
37 | Form1: TForm1;
38 |
39 | implementation
40 |
41 | uses
42 | IPC.Demo.Types;
43 | {$R *.dfm}
44 |
45 | procedure TForm1.ClientRecieveResponseIpcData(Sender: TObject; var ResponseData: Pointer);
46 | begin
47 | // MessageBoxW(0, TResponseData(ResponseData^).Text, 'IPC Client', 0);
48 | end;
49 |
50 | procedure TForm1.Button1Click(Sender: TObject);
51 | var
52 | Data: TData;
53 | ResponseData: Pointer;
54 | begin
55 | ResponseData := nil;
56 | Data.ProcessId := GetCurrentProcessId;
57 | Data.SetText(Memo1.Text);
58 | if not FIPCClient.Send('IPC Server', Data, CheckBox1.Checked, 1000, ResponseData) then
59 | Memo1.Lines.Add('Error send IPC data - ' + SysErrorMessage(FIPCClient.LastError));
60 | if ResponseData <> nil then
61 | begin
62 | MessageBeep(0);
63 | MessageBoxW(0, TResponseData(ResponseData^).Text, 'IPC Client', 0);
64 | end;
65 | end;
66 |
67 | procedure TForm1.FormCreate(Sender: TObject);
68 | begin
69 | FIPCClient := TIPCClient.Create(nil);
70 | if not FIPCClient.CreateClient('IPCClient_' + IntToStr(GetCurrentProcessId)) then
71 | Memo1.Lines.Add('Error create client "' + 'IPC Client' + '" - ' + SysErrorMessage(FIPCClient.LastError));
72 | FIPCClient.OnRecieveResponseIpcData := ClientRecieveResponseIpcData;
73 | end;
74 |
75 | procedure TForm1.FormDestroy(Sender: TObject);
76 | begin
77 | FIPCClient.Free;
78 | end;
79 |
80 | end.
81 |
82 |
--------------------------------------------------------------------------------
/Unit_Server.dfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 260
3 | Top = 127
4 | Caption = 'IPC Server'
5 | ClientHeight = 343
6 | ClientWidth = 877
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -14
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | OnClose = FormClose
15 | OnCreate = FormCreate
16 | DesignSize = (
17 | 877
18 | 343)
19 | PixelsPerInch = 120
20 | TextHeight = 17
21 | object Button1: TButton
22 | Left = 10
23 | Top = 311
24 | Width = 144
25 | Height = 33
26 | Anchors = [akLeft, akBottom]
27 | Caption = 'Create Server'
28 | TabOrder = 0
29 | OnClick = Button1Click
30 | end
31 | object Button2: TButton
32 | Left = 162
33 | Top = 311
34 | Width = 144
35 | Height = 33
36 | Anchors = [akLeft, akBottom]
37 | Caption = 'Free Server'
38 | Enabled = False
39 | TabOrder = 1
40 | OnClick = Button2Click
41 | end
42 | object Memo1: TMemo
43 | Left = 10
44 | Top = 10
45 | Width = 865
46 | Height = 253
47 | Anchors = [akLeft, akTop, akRight, akBottom]
48 | ScrollBars = ssVertical
49 | TabOrder = 2
50 | end
51 | object Edit1: TEdit
52 | Left = 10
53 | Top = 275
54 | Width = 865
55 | Height = 25
56 | Anchors = [akLeft, akRight, akBottom]
57 | TabOrder = 3
58 | Text = 'This is response text from server '
59 | end
60 | object Button3: TButton
61 | Left = 777
62 | Top = 311
63 | Width = 98
64 | Height = 33
65 | Anchors = [akRight, akBottom]
66 | Caption = 'Clear'
67 | TabOrder = 4
68 | OnClick = Button3Click
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/Unit_Server.pas:
--------------------------------------------------------------------------------
1 | unit Unit_Server;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows,
7 | Winapi.Messages,
8 | System.SysUtils,
9 | System.Variants,
10 | System.Classes,
11 | Vcl.Graphics,
12 | Vcl.Controls,
13 | Vcl.Forms,
14 | Vcl.Dialogs,
15 | Vcl.StdCtrls,
16 | Vcl.ExtCtrls,
17 | Vcl.ComCtrls,
18 | IPC;
19 |
20 | type
21 | TForm1 = class(TForm)
22 | Button1: TButton;
23 | Button2: TButton;
24 | Memo1: TMemo;
25 | Edit1: TEdit;
26 | Button3: TButton;
27 | procedure FormCreate(Sender: TObject);
28 | procedure Button1Click(Sender: TObject);
29 | procedure Button2Click(Sender: TObject);
30 | procedure FormClose(Sender: TObject; var Action: TCloseAction);
31 | procedure Button3Click(Sender: TObject);
32 | private
33 | { Private declarations }
34 | FIPCServer: TIPCServer;
35 | public
36 | { Public declarations }
37 | procedure ServerRecieveIpcData(Sender: TObject; var ClientName: WideString;
38 | var ClientWaitingForResponse: Boolean; var Data: Pointer);
39 | end;
40 |
41 | var
42 | Form1: TForm1;
43 |
44 | implementation
45 |
46 | uses
47 | IPC.Demo.Types;
48 | {$R *.dfm}
49 |
50 | procedure TForm1.ServerRecieveIpcData(Sender: TObject; var ClientName:
51 | WideString; var ClientWaitingForResponse: Boolean; var Data: Pointer);
52 | var
53 | ResponseData: TResponseData;
54 | begin
55 | Form1.Memo1.Lines.Add(ClientName + ': ' + TData(Data^).Text);
56 | if ClientWaitingForResponse then
57 | begin
58 | lstrcpynW(ResponseData.Text, PWideChar(Edit1.Text), MAX_LENGTH);
59 | if not FIPCServer.SendIpcData(ClientName, @ResponseData, SizeOf(TResponseData)) then
60 | Form1.Memo1.Lines.Add('Error send response - ' + SysErrorMessage(FIPCServer.LastError));
61 | end;
62 | end;
63 |
64 | procedure TForm1.Button1Click(Sender: TObject);
65 | begin
66 | if not FIPCServer.CreateServer('IPC Server') then
67 | Form1.Memo1.Lines.Add('Error create server "' + 'IPC Server' + '" - ' + SysErrorMessage(FIPCServer.LastError))
68 | else
69 | begin
70 | Button1.Enabled := False;
71 | Button2.Enabled := True;
72 | end;
73 | end;
74 |
75 | procedure TForm1.Button2Click(Sender: TObject);
76 | begin
77 | if FIPCServer.FreeServer then
78 | begin
79 | Button1.Enabled := True;
80 | Button2.Enabled := False;
81 | end;
82 | end;
83 |
84 | procedure TForm1.Button3Click(Sender: TObject);
85 | begin
86 | Memo1.Clear;
87 | end;
88 |
89 | procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
90 | begin
91 | FIPCServer.Free;
92 | end;
93 |
94 | procedure TForm1.FormCreate(Sender: TObject);
95 | begin
96 | FIPCServer := TIPCServer.Create(nil);
97 | FIPCServer.OnRecieveIpcData := ServerRecieveIpcData;
98 | Button1.Click;
99 | end;
100 |
101 | end.
102 |
103 |
--------------------------------------------------------------------------------