Subversion Repositories userdetect2

Rev

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