Rev 82 | Rev 84 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 82 | Rev 83 | ||
---|---|---|---|
Line 8... | Line 8... | ||
8 | 8 | ||
9 | {$INCLUDE 'UserDetect2.inc'} |
9 | {$INCLUDE 'UserDetect2.inc'} |
10 | 10 | ||
11 | uses |
11 | uses |
12 | Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf, |
12 | Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf, |
13 | UD2_PluginStatus; |
13 | UD2_PluginStatus, UD2_Utils; |
14 | 14 | ||
15 | const |
15 | const |
16 | cchBufferSize = 32768; |
16 | cchBufferSize = 32768; |
17 | 17 | ||
- | 18 | dynamicDataDelim = '|||'; |
|
- | 19 | ||
18 | type |
20 | type |
- | 21 | TUD2IdentificationEntry = class; |
|
- | 22 | ||
19 | TUD2Plugin = class(TObject) |
23 | TUD2Plugin = class(TObject) |
20 | protected |
24 | protected |
21 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
25 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
22 | public |
26 | public |
23 | // This flag will be set if "AutoOSNotSupportedCompatibility" of the INI manifest had to be enforced/used |
27 | // This flag will be set if "AutoOSNotSupportedCompatibility" of the INI manifest had to be enforced/used |
Line 34... | Line 38... | ||
34 | IdentificationProcedureStatusCode: UD2_STATUS; |
38 | IdentificationProcedureStatusCode: UD2_STATUS; |
35 | IdentificationProcedureStatusCodeDescribed: WideString; |
39 | IdentificationProcedureStatusCodeDescribed: WideString; |
36 | 40 | ||
37 | Time: Cardinal; |
41 | Time: Cardinal; |
38 | function PluginGUIDString: string; |
42 | function PluginGUIDString: string; |
39 | property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} |
43 | property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} read FDetectedIdentifications; |
40 | read FDetectedIdentifications; |
- | |
41 | destructor Destroy; override; |
44 | destructor Destroy; override; |
42 | constructor Create; |
45 | constructor Create; |
43 | procedure AddIdentification(IdStr: WideString); |
46 | function AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
- | 47 | ||
- | 48 | function InvokeDynamicCheck(dynamicData: string): boolean; |
|
- | 49 | function GetDynamicRequestResult(dynamicData: string): TArrayOfString; |
|
- | 50 | ||
- | 51 | function EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
|
44 | end; |
52 | end; |
45 | 53 | ||
46 | TUD2IdentificationEntry = class(TObject) |
54 | TUD2IdentificationEntry = class(TObject) |
47 | private |
55 | private |
48 | FIdentificationString: WideString; |
56 | FIdentificationString: WideString; |
49 | FPlugin: TUD2Plugin; |
57 | FPlugin: TUD2Plugin; |
- | 58 | FDynamicDataUsed: boolean; |
|
- | 59 | FDynamicData: string; |
|
50 | public |
60 | public |
- | 61 | property DynamicDataUsed: boolean read FDynamicDataUsed write FDynamicDataUsed; |
|
- | 62 | property DynamicData: string read FDynamicData write FDynamicData; |
|
51 | property IdentificationString: WideString read FIdentificationString; |
63 | property IdentificationString: WideString read FIdentificationString; |
52 | property Plugin: TUD2Plugin read FPlugin; |
64 | property Plugin: TUD2Plugin read FPlugin; |
53 | function GetPrimaryIdName: WideString; |
- | |
54 | procedure GetIdNames(sl: TStrings); |
65 | procedure GetIdNames(sl: TStrings); |
55 | constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin); |
66 | constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin); |
56 | end; |
67 | end; |
57 | 68 | ||
58 | TUD2 = class(TObject) |
69 | TUD2 = class(TObject) |
Line 70... | Line 81... | ||
70 | property Errors: TStrings read FErrors; |
81 | property Errors: TStrings read FErrors; |
71 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
82 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
72 | property IniFile: TMemIniFile read FIniFile; |
83 | property IniFile: TMemIniFile read FIniFile; |
73 | procedure GetAllIdNames(outSL: TStrings); |
84 | procedure GetAllIdNames(outSL: TStrings); |
74 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
85 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
- | 86 | procedure CheckTerm(idTermAndCmd: string; commandSLout: TStrings; slIdNames: TStrings=nil); |
|
- | 87 | function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
|
75 | procedure GetCommandList(ShortTaskName: string; outSL: TStrings); |
88 | procedure GetCommandList(ShortTaskName: string; outSL: TStrings); |
76 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
89 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
77 | procedure GetTaskListing(outSL: TStrings); |
90 | procedure GetTaskListing(outSL: TStrings); |
78 | constructor Create(AIniFileName: string); |
91 | constructor Create(AIniFileName: string); |
79 | destructor Destroy; override; |
92 | destructor Destroy; override; |
Line 85... | Line 98... | ||
85 | end; |
98 | end; |
86 | 99 | ||
87 | implementation |
100 | implementation |
88 | 101 | ||
89 | uses |
102 | uses |
90 | UD2_Utils; |
103 | Math; |
91 | 104 | ||
92 | type |
105 | type |
93 | TUD2PluginLoader = class(TThread) |
106 | TUD2PluginLoader = class(TThread) |
94 | protected |
107 | protected |
95 | dllFile: string; |
108 | dllFile: string; |
96 | lngID: LANGID; |
109 | lngID: LANGID; |
- | 110 | useDynamicData: boolean; |
|
- | 111 | dynamicData: WideString; |
|
97 | procedure Execute; override; |
112 | procedure Execute; override; |
98 | function HandleDLL: boolean; |
113 | function HandleDLL: boolean; |
99 | public |
114 | public |
100 | pl: TUD2Plugin; |
115 | pl: TUD2Plugin; // TODO: why do we need it?! can it be leaked if we use it for dynamic requests? |
101 | Errors: TStringList; |
116 | Errors: TStringList; |
- | 117 | ResultIdentifiers: TArrayOfString; |
|
102 | constructor Create(Suspended: boolean; DLL: string; alngid: LANGID); |
118 | constructor Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
103 | destructor Destroy; override; |
119 | destructor Destroy; override; |
104 | end; |
120 | end; |
105 | 121 | ||
106 | class function TUD2.GenericErrorLookup(grStatus: UD2_STATUS): string; |
122 | class function TUD2.GenericErrorLookup(grStatus: UD2_STATUS): string; |
107 | resourcestring |
123 | resourcestring |
Line 113... | Line 129... | ||
113 | LNG_STATUS_NOTAVAIL_UNSPECIFIED = 'Not available (Unspecified)'; |
129 | LNG_STATUS_NOTAVAIL_UNSPECIFIED = 'Not available (Unspecified)'; |
114 | LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED = 'Not available (Operating system not supported)'; |
130 | LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED = 'Not available (Operating system not supported)'; |
115 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
131 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
116 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
132 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
117 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
133 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
- | 134 | LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC = 'Not available (Arguments required)'; |
|
118 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
135 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
119 | 136 | ||
120 | LNG_STATUS_FAILURE_UNSPECIFIED = 'Error (Unspecified)'; |
137 | LNG_STATUS_FAILURE_UNSPECIFIED = 'Error (Unspecified)'; |
121 | LNG_STATUS_FAILURE_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
138 | LNG_STATUS_FAILURE_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
122 | LNG_STATUS_FAILURE_INVALID_ARGS = 'Error (The function received invalid arguments!)'; |
139 | LNG_STATUS_FAILURE_INVALID_ARGS = 'Error (The function received invalid arguments!)'; |
Line 134... | Line 151... | ||
134 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_UNSPECIFIED, false) then result := LNG_STATUS_NOTAVAIL_UNSPECIFIED |
151 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_UNSPECIFIED, false) then result := LNG_STATUS_NOTAVAIL_UNSPECIFIED |
135 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
152 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
136 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
153 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
137 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
154 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
138 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE, false) then result := Format(LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE, [FormatOSError(grStatus.dwExtraInfo)]) |
155 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE, false) then result := Format(LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE, [FormatOSError(grStatus.dwExtraInfo)]) |
- | 156 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC, false) then result := LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC |
|
139 | 157 | ||
140 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_FAILURE_UNSPECIFIED |
158 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_FAILURE_UNSPECIFIED |
141 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL |
159 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL |
142 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_FAILURE_INVALID_ARGS |
160 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_FAILURE_INVALID_ARGS |
143 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED |
161 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED |
Line 155... | Line 173... | ||
155 | function TUD2Plugin.PluginGUIDString: string; |
173 | function TUD2Plugin.PluginGUIDString: string; |
156 | begin |
174 | begin |
157 | result := UpperCase(GUIDToString(PluginGUID)); |
175 | result := UpperCase(GUIDToString(PluginGUID)); |
158 | end; |
176 | end; |
159 | 177 | ||
160 | procedure TUD2Plugin.AddIdentification(IdStr: WideString); |
178 | function TUD2Plugin.AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
161 | begin |
179 | begin |
162 | DetectedIdentifications.Add(TUD2IdentificationEntry.Create(IdStr, Self)) |
180 | result := TUD2IdentificationEntry.Create(IdStr, Self); |
- | 181 | DetectedIdentifications.Add(result); |
|
163 | end; |
182 | end; |
164 | 183 | ||
165 | destructor TUD2Plugin.Destroy; |
184 | destructor TUD2Plugin.Destroy; |
166 | begin |
185 | begin |
167 | DetectedIdentifications.Free; |
186 | DetectedIdentifications.Free; |
Line 172... | Line 191... | ||
172 | begin |
191 | begin |
173 | inherited Create; |
192 | inherited Create; |
174 | FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true); |
193 | FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true); |
175 | end; |
194 | end; |
176 | 195 | ||
- | 196 | function TUD2Plugin.InvokeDynamicCheck(dynamicData: string): boolean; |
|
- | 197 | var |
|
177 | { TUD2IdentificationEntry } |
198 | ude: TUD2IdentificationEntry; |
- | 199 | i: integer; |
|
- | 200 | ids: TArrayOfString; |
|
- | 201 | id: string; |
|
- | 202 | begin |
|
- | 203 | result := false; |
|
- | 204 | ||
- | 205 | for i := 0 to FDetectedIdentifications.Count-1 do |
|
- | 206 | begin |
|
- | 207 | ude := FDetectedIdentifications.Items[i] as TUD2IdentificationEntry; |
|
- | 208 | if ude.dynamicDataUsed and (ude.dynamicData = dynamicData) then |
|
- | 209 | begin |
|
- | 210 | // The dynamic content was already evaluated (and therefore is already added in FDetectedIdentifications). |
|
- | 211 | Exit; |
|
- | 212 | end; |
|
- | 213 | end; |
|
- | 214 | ||
- | 215 | SetLength(ids, 0); |
|
- | 216 | ids := GetDynamicRequestResult(dynamicData); |
|
- | 217 | ||
- | 218 | for i := 0 to Length(ids)-1 do |
|
- | 219 | begin |
|
- | 220 | id := ids[i]; |
|
- | 221 | ||
- | 222 | ude := AddIdentification(id); |
|
- | 223 | ude.dynamicDataUsed := true; |
|
- | 224 | ude.dynamicData := dynamicData; |
|
- | 225 | ||
- | 226 | result := true; |
|
- | 227 | end; |
|
- | 228 | end; |
|
- | 229 | ||
- | 230 | function TUD2Plugin.GetDynamicRequestResult(dynamicData: string): TArrayOfString; |
|
- | 231 | var |
|
- | 232 | lngID: LANGID; |
|
- | 233 | pll: TUD2PluginLoader; |
|
- | 234 | begin |
|
- | 235 | lngID := GetSystemDefaultLangID; |
|
- | 236 | ||
- | 237 | pll := TUD2PluginLoader.Create(false, PluginDLL, lngid, true, dynamicData); |
|
- | 238 | try |
|
- | 239 | pll.WaitFor; |
|
- | 240 | result := pll.ResultIdentifiers; |
|
- | 241 | finally |
|
- | 242 | pll.Free; |
|
- | 243 | end; |
|
- | 244 | end; |
|
178 | 245 | ||
179 | function TUD2IdentificationEntry.GetPrimaryIdName: WideString; |
246 | function TUD2Plugin.EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
180 | begin |
247 | begin |
181 | result := Plugin.IdentificationMethodName+':'+IdentificationString; |
248 | result := SameText(IdentificationMethodName, idMethodNameOrGUID) or |
- | 249 | SameText(GUIDToString(PluginGUID), idMethodNameOrGUID) |
|
182 | end; |
250 | end; |
183 | 251 | ||
- | 252 | { TUD2IdentificationEntry } |
|
- | 253 | ||
184 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
254 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
185 | begin |
255 | begin |
186 | sl.Add(GetPrimaryIdName); |
256 | if DynamicDataUsed then |
- | 257 | begin |
|
- | 258 | sl.Add(DynamicData+dynamicDataDelim+Plugin.IdentificationMethodName+':'+IdentificationString); |
|
- | 259 | sl.Add(DynamicData+DynamicDataDelim+Plugin.PluginGUIDString+':'+IdentificationString); |
|
- | 260 | end |
|
- | 261 | else |
|
- | 262 | begin |
|
187 | sl.Add(Plugin.IdentificationMethodName+':'+IdentificationString); |
263 | sl.Add(Plugin.IdentificationMethodName+':'+IdentificationString); |
188 | sl.Add(Plugin.PluginGUIDString+':'+IdentificationString); |
264 | sl.Add(Plugin.PluginGUIDString+':'+IdentificationString); |
189 | end; |
265 | end; |
- | 266 | end; |
|
190 | 267 | ||
191 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
268 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
192 | APlugin: TUD2Plugin); |
269 | APlugin: TUD2Plugin); |
193 | begin |
270 | begin |
194 | inherited Create; |
271 | inherited Create; |
Line 224... | Line 301... | ||
224 | if FindFirst(path + AFileMask, 0, SR) = 0 then |
301 | if FindFirst(path + AFileMask, 0, SR) = 0 then |
225 | begin |
302 | begin |
226 | try |
303 | try |
227 | repeat |
304 | repeat |
228 | try |
305 | try |
229 | tob.Add(TUD2PluginLoader.Create(false, path + sr.Name, lngid)); |
306 | tob.Add(TUD2PluginLoader.Create(false, path + sr.Name, lngid, false, '')); |
230 | except |
307 | except |
231 | on E: Exception do |
308 | on E: Exception do |
232 | begin |
309 | begin |
233 | MessageDlg(E.Message, mtError, [mbOK], 0); |
310 | MessageDlg(E.Message, mtError, [mbOK], 0); |
234 | end; |
311 | end; |
Line 337... | Line 414... | ||
337 | result := BetterInterpreteBool(IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal)); |
414 | result := BetterInterpreteBool(IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal)); |
338 | end; |
415 | end; |
339 | 416 | ||
340 | (* |
417 | (* |
341 | 418 | ||
342 | NAMING EXAMPLE: ComputerName:ABC&&User:John=calc.exe |
419 | NAMING EXAMPLE: dynXYZ|||ComputerName:ABC&&User:John=calc.exe |
343 | 420 | ||
344 | idTerm: ComputerName:ABC&&User:John |
421 | idTerm: dynXYZ|||ComputerName:ABC&&User:John |
345 | idName: ComputerName:ABC |
422 | idName: ComputerName:ABC |
346 | IdMethodName: ComputerName |
423 | IdMethodName: ComputerName |
347 | IdStr ABC |
424 | IdStr ABC |
348 | cmd: calc.exe |
425 | cmd: calc.exe |
- | 426 | dynamicData: dynXYZ |
|
349 | 427 | ||
350 | *) |
428 | *) |
351 | 429 | ||
352 | procedure TUD2.GetAllIdNames(outSL: TStrings); |
430 | procedure TUD2.GetAllIdNames(outSL: TStrings); |
353 | var |
431 | var |
Line 368... | Line 446... | ||
368 | 446 | ||
369 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
447 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
370 | const |
448 | const |
371 | CASE_SENSITIVE_FLAG = '$CASESENSITIVE$'; |
449 | CASE_SENSITIVE_FLAG = '$CASESENSITIVE$'; |
372 | var |
450 | var |
373 | x: TArrayOfString; |
451 | x, y, z: TArrayOfString; |
374 | i: integer; |
452 | i: integer; |
- | 453 | p: TUD2Plugin; |
|
375 | idName: WideString; |
454 | idName: WideString; |
376 | cleanUpStringList: boolean; |
455 | cleanUpStringList: boolean; |
377 | caseSensitive: boolean; |
456 | caseSensitive: boolean; |
- | 457 | dynamicData: string; |
|
- | 458 | idMethodName: string; |
|
378 | begin |
459 | begin |
379 | cleanUpStringList := slIdNames = nil; |
460 | cleanUpStringList := slIdNames = nil; |
380 | try |
461 | try |
381 | if cleanUpStringList then |
462 | if cleanUpStringList then |
382 | begin |
463 | begin |
Line 385... | Line 466... | ||
385 | end; |
466 | end; |
386 | 467 | ||
387 | SetLength(x, 0); |
468 | SetLength(x, 0); |
388 | if Pos(':', idTerm) = 0 then |
469 | if Pos(':', idTerm) = 0 then |
389 | begin |
470 | begin |
- | 471 | // Exclude stuff like "Description" |
|
390 | result := false; |
472 | result := false; |
391 | Exit; |
473 | Exit; |
392 | end; |
474 | end; |
393 | x := SplitString('&&', idTerm); |
475 | x := SplitString('&&', idTerm); |
394 | result := true; |
476 | result := true; |
395 | for i := Low(x) to High(x) do |
477 | for i := Low(x) to High(x) do |
396 | begin |
478 | begin |
397 | idName := x[i]; |
479 | idName := x[i]; |
398 | 480 | ||
- | 481 | /// --- Start Dynamic Extension |
|
- | 482 | ||
- | 483 | SetLength(y, 0); |
|
- | 484 | y := SplitString(dynamicDataDelim, idName); |
|
- | 485 | ||
- | 486 | if Length(y) >= 2 then |
|
- | 487 | begin |
|
- | 488 | dynamicData := y[0]; |
|
- | 489 | ||
- | 490 | SetLength(z, 0); |
|
- | 491 | z := SplitString(':', y[1]); |
|
- | 492 | idMethodName := z[0]; |
|
- | 493 | ||
- | 494 | p := FindPluginByMethodNameOrGuid(idMethodName); |
|
- | 495 | if Assigned(p) then |
|
- | 496 | begin |
|
- | 497 | if p.InvokeDynamicCheck(dynamicData) then |
|
- | 498 | begin |
|
- | 499 | // Reload the identifications |
|
- | 500 | slIdNames.Clear; |
|
- | 501 | GetAllIdNames(slIdNames); |
|
- | 502 | end; |
|
- | 503 | end; |
|
- | 504 | end; |
|
- | 505 | ||
- | 506 | /// --- End Dynamic Extension |
|
- | 507 | ||
399 | if Pos(CASE_SENSITIVE_FLAG, idName) >= 1 then |
508 | if Pos(CASE_SENSITIVE_FLAG, idName) >= 1 then |
400 | begin |
509 | begin |
401 | idName := StringReplace(idName, CASE_SENSITIVE_FLAG, '', [rfReplaceAll]); |
510 | idName := StringReplace(idName, CASE_SENSITIVE_FLAG, '', [rfReplaceAll]); |
402 | caseSensitive := true; |
511 | caseSensitive := true; |
403 | end |
512 | end |
Line 417... | Line 526... | ||
417 | if cleanUpStringList and Assigned(slIdNames) then |
526 | if cleanUpStringList and Assigned(slIdNames) then |
418 | slIdNames.Free; |
527 | slIdNames.Free; |
419 | end; |
528 | end; |
420 | end; |
529 | end; |
421 | 530 | ||
- | 531 | function TUD2.FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
|
- | 532 | var |
|
- | 533 | i: integer; |
|
- | 534 | p: TUD2Plugin; |
|
- | 535 | begin |
|
- | 536 | result := nil; |
|
- | 537 | for i := 0 to LoadedPlugins.Count-1 do |
|
- | 538 | begin |
|
- | 539 | p := LoadedPlugins.Items[i] as TUD2Plugin; |
|
- | 540 | ||
- | 541 | if p.EqualsMethodNameOrGuid(idMethodName) then |
|
- | 542 | begin |
|
- | 543 | result := p; |
|
- | 544 | Exit; |
|
- | 545 | end; |
|
- | 546 | end; |
|
- | 547 | end; |
|
- | 548 | ||
422 | procedure TUD2.GetCommandList(ShortTaskName: string; outSL: TStrings); |
549 | procedure TUD2.GetCommandList(ShortTaskName: string; outSL: TStrings); |
423 | var |
550 | var |
424 | i: integer; |
551 | i: integer; |
425 | cmd: string; |
- | |
426 | idTerm: WideString; |
- | |
427 | slSV, slIdNames: TStrings; |
552 | slSV, slIdNames: TStrings; |
428 | nameVal: TArrayOfString; |
- | |
429 | begin |
553 | begin |
430 | SetLength(nameVal, 0); |
- | |
431 | - | ||
432 | slIdNames := TStringList.Create; |
554 | slIdNames := TStringList.Create; |
433 | try |
555 | try |
434 | GetAllIdNames(slIdNames); |
556 | GetAllIdNames(slIdNames); |
435 | 557 | ||
436 | slSV := TStringList.Create; |
558 | slSV := TStringList.Create; |
437 | try |
559 | try |
438 | FIniFile.ReadSectionValues(ShortTaskName, slSV); |
560 | FIniFile.ReadSectionValues(ShortTaskName, slSV); |
439 | for i := 0 to slSV.Count-1 do |
561 | for i := 0 to slSV.Count-1 do |
440 | begin |
562 | begin |
- | 563 | CheckTerm(slSV.Strings[i], outSL, slIdNames); |
|
- | 564 | end; |
|
- | 565 | finally |
|
- | 566 | slSV.Free; |
|
- | 567 | end; |
|
- | 568 | finally |
|
- | 569 | slIdNames.Free; |
|
- | 570 | end; |
|
- | 571 | end; |
|
- | 572 | ||
- | 573 | procedure TUD2.CheckTerm(idTermAndCmd: string; commandSLout: TStrings; slIdNames: TStrings=nil); |
|
- | 574 | var |
|
- | 575 | nameVal: TArrayOfString; |
|
- | 576 | idTerm, cmd: string; |
|
- | 577 | slIdNamesCreated: boolean; |
|
- | 578 | begin |
|
- | 579 | slIdNamesCreated := false; |
|
- | 580 | try |
|
- | 581 | if not Assigned(slIdNames) then |
|
- | 582 | begin |
|
- | 583 | slIdNamesCreated := true; |
|
- | 584 | slIdNames := TStringList.Create; |
|
- | 585 | GetAllIdNames(slIdNames); |
|
- | 586 | end; |
|
- | 587 | ||
- | 588 | SetLength(nameVal, 0); |
|
- | 589 | ||
441 | // We are doing the interpretation of the line ourselves, because |
590 | // We are doing the interpretation of the line ourselves, because |
442 | // TStringList.Values[] would not allow multiple command lines with the |
591 | // TStringList.Values[] would not allow multiple command lines with the |
443 | // same key (idTerm) |
592 | // same key (idTerm) |
- | 593 | // TODO xxx: big problem when we want to check environment variables, since our idTerm would contain '=' ! |
|
444 | nameVal := SplitString('=', slSV.Strings[i]); |
594 | nameVal := SplitString('=', idTermAndCmd); |
- | 595 | if Length(nameVal) < 2 then exit; |
|
445 | idTerm := nameVal[0]; |
596 | idTerm := nameVal[0]; |
446 | cmd := nameVal[1]; |
597 | cmd := nameVal[1]; |
447 | 598 | ||
448 | if FulfilsEverySubterm(idTerm, slIdNames) then outSL.Add(cmd); |
599 | if FulfilsEverySubterm(idTerm, slIdNames) then commandSLout.Add(cmd); |
449 | end; |
- | |
450 | finally |
600 | finally |
451 | slSV.Free; |
- | |
452 | end; |
- | |
453 | finally |
- | |
454 | slIdNames.Free; |
601 | if slIdNamesCreated then slIdNames.Free; |
455 | end; |
602 | end; |
456 | end; |
603 | end; |
457 | 604 | ||
458 | { TUD2PluginLoader } |
605 | { TUD2PluginLoader } |
459 | 606 | ||
Line 462... | Line 609... | ||
462 | inherited; |
609 | inherited; |
463 | 610 | ||
464 | HandleDLL; |
611 | HandleDLL; |
465 | end; |
612 | end; |
466 | 613 | ||
467 | constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID); |
614 | constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
468 | begin |
615 | begin |
469 | inherited Create(Suspended); |
616 | inherited Create(Suspended); |
470 | dllfile := dll; |
617 | dllfile := dll; |
471 | pl := nil; |
618 | pl := nil; |
472 | Errors := TStringList.Create; |
619 | Errors := TStringList.Create; |
473 | lngid := alngid; |
620 | lngid := alngid; |
- | 621 | self.useDynamicData := useDynamicData; |
|
- | 622 | Self.dynamicData := dynamicData; |
|
474 | end; |
623 | end; |
475 | 624 | ||
476 | destructor TUD2PluginLoader.Destroy; |
625 | destructor TUD2PluginLoader.Destroy; |
477 | begin |
626 | begin |
478 | Errors.Free; |
627 | Errors.Free; |
Line 480... | Line 629... | ||
480 | end; |
629 | end; |
481 | 630 | ||
482 | function TUD2PluginLoader.HandleDLL: boolean; |
631 | function TUD2PluginLoader.HandleDLL: boolean; |
483 | var |
632 | var |
484 | sIdentifier: WideString; |
633 | sIdentifier: WideString; |
485 | sIdentifiers: TArrayOfString; |
- | |
486 | buf: array[0..cchBufferSize-1] of WideChar; |
634 | buf: array[0..cchBufferSize-1] of WideChar; |
487 | pluginInterfaceID: TGUID; |
635 | pluginInterfaceID: TGUID; |
488 | dllHandle: Cardinal; |
636 | dllHandle: Cardinal; |
489 | fPluginInterfaceID: TFuncPluginInterfaceID; |
637 | fPluginInterfaceID: TFuncPluginInterfaceID; |
490 | fPluginIdentifier: TFuncPluginIdentifier; |
638 | fPluginIdentifier: TFuncPluginIdentifier; |
491 | fPluginNameW: TFuncPluginNameW; |
639 | fPluginNameW: TFuncPluginNameW; |
492 | fPluginVendorW: TFuncPluginVendorW; |
640 | fPluginVendorW: TFuncPluginVendorW; |
493 | fPluginVersionW: TFuncPluginVersionW; |
641 | fPluginVersionW: TFuncPluginVersionW; |
494 | fIdentificationMethodNameW: TFuncIdentificationMethodNameW; |
642 | fIdentificationMethodNameW: TFuncIdentificationMethodNameW; |
495 | fIdentificationStringW: TFuncIdentificationStringW; |
643 | fIdentificationStringW: TFuncIdentificationStringW; |
- | 644 | fDynamicIdentificationStringW: TFuncDynamicIdentificationStringW; |
|
496 | fCheckLicense: TFuncCheckLicense; |
645 | fCheckLicense: TFuncCheckLicense; |
497 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
646 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
498 | statusCode: UD2_STATUS; |
647 | statusCode: UD2_STATUS; |
499 | i: integer; |
648 | i: integer; |
500 | starttime, endtime, time: cardinal; |
649 | starttime, endtime, time: cardinal; |
Line 502... | Line 651... | ||
502 | err: DWORD; |
651 | err: DWORD; |
503 | 652 | ||
504 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
653 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
505 | var |
654 | var |
506 | ret: BOOL; |
655 | ret: BOOL; |
- | 656 | buf: array[0..cchBufferSize-1] of WideChar; |
|
507 | begin |
657 | begin |
508 | if Assigned(fDescribeOwnStatusCodeW) then |
658 | if Assigned(fDescribeOwnStatusCodeW) then |
509 | begin |
659 | begin |
510 | ZeroMemory(@buf, cchBufferSize); |
660 | ZeroMemory(@buf, cchBufferSize); |
511 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
661 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
Line 618... | Line 768... | ||
618 | begin |
768 | begin |
619 | Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile])); |
769 | Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile])); |
620 | Exit; |
770 | Exit; |
621 | end; |
771 | end; |
622 | 772 | ||
- | 773 | fDynamicIdentificationStringW := nil; |
|
- | 774 | fIdentificationStringW := nil; |
|
- | 775 | if useDynamicData then |
|
- | 776 | begin |
|
- | 777 | @fDynamicIdentificationStringW := GetProcAddress(dllHandle, mnDynamicIdentificationStringW); |
|
- | 778 | if not Assigned(fDynamicIdentificationStringW) then |
|
- | 779 | begin |
|
- | 780 | // TODO xxx: Darf hier ein fataler Fehler entstehen, obwohl dieses Szenario nur durch die INI file auftreten kann? |
|
- | 781 | // TODO (allgemein): In der Modulübersicht soll auch gezeigt werden, ob dieses Modul dynamischen Content erlaubt. |
|
- | 782 | // TODO (allgemein): doku |
|
- | 783 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile])); |
|
- | 784 | Exit; |
|
- | 785 | end; |
|
- | 786 | end |
|
- | 787 | else |
|
- | 788 | begin |
|
623 | @fIdentificationStringW := GetProcAddress(dllHandle, mnIdentificationStringW); |
789 | @fIdentificationStringW := GetProcAddress(dllHandle, mnIdentificationStringW); |
624 | if not Assigned(fIdentificationStringW) then |
790 | if not Assigned(fIdentificationStringW) then |
625 | begin |
791 | begin |
626 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationStringW, dllFile])); |
792 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationStringW, dllFile])); |
627 | Exit; |
793 | Exit; |
628 | end; |
794 | end; |
- | 795 | end; |
|
629 | 796 | ||
630 | @fPluginNameW := GetProcAddress(dllHandle, mnPluginNameW); |
797 | @fPluginNameW := GetProcAddress(dllHandle, mnPluginNameW); |
631 | if not Assigned(fPluginNameW) then |
798 | if not Assigned(fPluginNameW) then |
632 | begin |
799 | begin |
633 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginNameW, dllFile])); |
800 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginNameW, dllFile])); |
Line 730... | Line 897... | ||
730 | Exit; |
897 | Exit; |
731 | end; |
898 | end; |
732 | 899 | ||
733 | ZeroMemory(@buf, cchBufferSize); |
900 | ZeroMemory(@buf, cchBufferSize); |
734 | statusCode := UD2_STATUS_FAILURE_NO_RETURNED_VALUE; // This status will be used when the DLL does not return anything (which is an error by the developer) |
901 | statusCode := UD2_STATUS_FAILURE_NO_RETURNED_VALUE; // This status will be used when the DLL does not return anything (which is an error by the developer) |
- | 902 | if useDynamicData then |
|
- | 903 | begin |
|
- | 904 | statusCode := fDynamicIdentificationStringW(@buf, cchBufferSize, PWideChar(dynamicData)); |
|
- | 905 | end |
|
- | 906 | else |
|
- | 907 | begin |
|
735 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
908 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
- | 909 | end; |
|
736 | pl.IdentificationProcedureStatusCode := statusCode; |
910 | pl.IdentificationProcedureStatusCode := statusCode; |
737 | pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
911 | pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
738 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
912 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
739 | begin |
913 | begin |
740 | sIdentifier := PWideChar(@buf); |
914 | sIdentifier := PWideChar(@buf); |
741 | if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then |
915 | if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then |
742 | begin |
916 | begin |
743 | // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER) |
917 | // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER) |
744 | SetLength(sIdentifiers, 0); |
918 | SetLength(ResultIdentifiers, 0); |
745 | sIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier); |
919 | ResultIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier); |
746 | for i := Low(sIdentifiers) to High(sIdentifiers) do |
920 | for i := Low(ResultIdentifiers) to High(ResultIdentifiers) do |
747 | begin |
921 | begin |
748 | pl.AddIdentification(sIdentifiers[i]); |
922 | pl.AddIdentification(ResultIdentifiers[i]); |
749 | end; |
923 | end; |
750 | end |
924 | end |
751 | else |
925 | else |
752 | begin |
926 | begin |
753 | pl.AddIdentification(sIdentifier); |
927 | pl.AddIdentification(sIdentifier); |
- | 928 | ||
- | 929 | SetLength(ResultIdentifiers, 1); |
|
- | 930 | ResultIdentifiers[0] := sIdentifier; |
|
754 | end; |
931 | end; |
755 | end |
932 | end |
756 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
933 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
757 | begin |
934 | begin |
758 | if _AutoOSNotSupportedMode >= 3 then |
935 | if _AutoOSNotSupportedMode >= 3 then |