-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprocesssharedstring.pas
executable file
·150 lines (131 loc) · 3.23 KB
/
processsharedstring.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
unit processsharedstring;
interface
uses
SysUtils,
Classes,
Windows;
type
TProcessSharedAnsiString = class
private
FIdentifier: AnsiString;
MappedFileSentry: THandle;
MappingHandle: THandle;
function MapView(Count: Int64): Pointer;
function UnmapView(Ptr: Pointer): Boolean;
function GetValue: AnsiString;
procedure SetValue(const Value: AnsiString);
procedure AcquireMutex;
procedure ReleaseMutex;
public
constructor Create(GlobalName: AnsiString);
destructor Destroy; override;
property Value: AnsiString read GetValue write SetValue;
procedure Lock;
procedure Unlock;
end;
implementation
const
MappedFileSize = 16384;
{ TProcessSharedAnsiString }
procedure TProcessSharedAnsiString.AcquireMutex;
begin
WaitForSingleObject(MappedFileSentry, INFINITE);
end;
constructor TProcessSharedAnsiString.Create(GlobalName: AnsiString);
begin
inherited Create;
MappedFileSentry := CreateMutex(nil, False, '7B31BF45-60D3-4F07-8308-DD7FEC8D065B');
AcquireMutex;
try
MappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PAnsiChar(GlobalName));
if MappingHandle = 0 then
begin
MappingHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
MappedFileSize, PAnsiChar(GlobalName));
SetValue('');
end;
finally
ReleaseMutex;
end;
FIdentifier := GlobalName;
end;
destructor TProcessSharedAnsiString.Destroy;
begin
CloseHandle(MappedFileSentry);
inherited;
end;
function TProcessSharedAnsiString.GetValue: AnsiString;
var
P: Pointer;
J: Integer;
begin
Result := '';
AcquireMutex;
try
P := MapView(MappedFileSize);
if P <> nil then
try
SetLength(Result, Integer(P^));
Cardinal(P) := Cardinal(P) + 4;
for J := 1 to Length(Result) do
begin
Result[J] := AnsiChar(P^);
Cardinal(P) := Cardinal(P) + 1;
end;
finally
UnmapView(P);
end;
finally
ReleaseMutex;
end;
end;
procedure TProcessSharedAnsiString.Lock;
begin
AcquireMutex;
end;
function TProcessSharedAnsiString.MapView(Count: Int64): Pointer;
begin
Result := MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, Count);
if Result = nil then
raise Exception.Create('Could not map view of file: ' + FIdentifier);
end;
procedure TProcessSharedAnsiString.ReleaseMutex;
begin
Windows.ReleaseMutex(MappedFileSentry);
end;
procedure TProcessSharedAnsiString.SetValue(const Value: AnsiString);
var
P: Pointer;
I, J: Integer;
begin
AcquireMutex;
try
P := MapView(MappedFileSize);
if P <> nil then
try
I := Length(Value);
if I > MappedFileSize - 4 then
I := MappedFileSize - 4;
Integer(P^) := I;
Cardinal(P) := Cardinal(P) + 4;
for J := 1 to I do
begin
AnsiChar(P^) := Value[J];
Cardinal(P) := Cardinal(P) + 1;
end;
finally
UnmapView(P);
end;
finally
ReleaseMutex;
end;
end;
procedure TProcessSharedAnsiString.Unlock;
begin
ReleaseMutex;
end;
function TProcessSharedAnsiString.UnmapView(Ptr: Pointer): Boolean;
begin
Result := UnmapViewOfFile(Ptr);
end;
end.