Subversion Repositories userdetect2

Rev

Rev 87 | Rev 91 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 87 Rev 90
Line 10... Line 10...
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, UD2_Utils, UD2_Parsing;
13
  UD2_PluginStatus, UD2_Utils, UD2_Parsing;
14
 
14
 
-
 
15
const
-
 
16
  UD2_TagDescription = 'Description';
-
 
17
 
15
type
18
type
16
  TUD2IdentificationEntry = class;
19
  TUD2IdentificationEntry = class;
17
 
20
 
18
  TUD2Plugin = class(TObject)
21
  TUD2Plugin = class(TObject)
19
  protected
22
  protected
Line 55... Line 58...
55
    property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} read FDetectedIdentifications;
58
    property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} read FDetectedIdentifications;
56
    destructor Destroy; override;
59
    destructor Destroy; override;
57
    constructor Create;
60
    constructor Create;
58
    function AddIdentification(IdStr: WideString): TUD2IdentificationEntry;
61
    function AddIdentification(IdStr: WideString): TUD2IdentificationEntry;
59
 
62
 
60
    function InvokeDynamicCheck(dynamicData: WideString; var outIDs: TArrayOfString): boolean; overload;
63
    function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean; overload;
61
    function InvokeDynamicCheck(dynamicData: WideString): boolean; overload;
64
    function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean; overload;
62
    function GetDynamicRequestResult(dynamicData: WideString): TArrayOfString;
65
    function GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString;
63
 
66
 
64
    function EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean;
67
    function EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean;
65
  end;
68
  end;
66
 
69
 
67
  TUD2IdentificationEntry = class(TObject)
70
  TUD2IdentificationEntry = class(TObject)
Line 93... Line 96...
93
    property IniFileName: string read FIniFileName;
96
    property IniFileName: string read FIniFileName;
94
    property Errors: TStrings read FErrors;
97
    property Errors: TStrings read FErrors;
95
    property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins;
98
    property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins;
96
    property IniFile: TMemIniFile read FIniFile;
99
    property IniFile: TMemIniFile read FIniFile;
97
    procedure GetAllDetectedIDs(outSL: TStrings);
100
    procedure GetAllDetectedIDs(outSL: TStrings);
98
    function FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil): boolean; overload;
101
    function FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload;
99
    function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; overload;
102
    function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload;
100
    function CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil): TUD2CommandArray;
103
    function CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray;
101
    function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin;
104
    function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin;
102
    function GetCommandList(ShortTaskName: string): TUD2CommandArray;
105
    function GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray;
103
    procedure HandlePluginDir(APluginDir, AFileMask: string);
106
    procedure HandlePluginDir(APluginDir, AFileMask: string);
104
    procedure GetTaskListing(outSL: TStrings);
107
    procedure GetTaskListing(outSL: TStrings);
105
    constructor Create(AIniFileName: string);
108
    constructor Create(AIniFileName: string);
106
    destructor Destroy; override;
109
    destructor Destroy; override;
107
    function TaskExists(ShortTaskName: string): boolean;
110
    function TaskExists(ShortTaskName: string): boolean;
Line 127... Line 130...
127
    useDynamicData: boolean;
130
    useDynamicData: boolean;
128
    dynamicData: WideString;
131
    dynamicData: WideString;
129
    procedure Execute; override;
132
    procedure Execute; override;
130
    function HandleDLL: boolean;
133
    function HandleDLL: boolean;
131
  public
134
  public
132
    pl: TUD2Plugin;
135
    Plugin: TUD2Plugin;
133
    Errors: TStringList;
136
    Errors: TStringList;
134
    ResultIdentifiers: TArrayOfString;
137
    ResultIdentifiers: TArrayOfString;
135
    constructor Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString);
138
    constructor Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString);
136
    destructor Destroy; override;
139
    destructor Destroy; override;
137
  end;
140
  end;
Line 147... Line 150...
147
  LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED    = 'Not available (Operating system not supported)';
150
  LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED    = 'Not available (Operating system not supported)';
148
  LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED    = 'Not available (Hardware not supported)';
151
  LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED    = 'Not available (Hardware not supported)';
149
  LNG_STATUS_NOTAVAIL_NO_ENTITIES         = 'Not available (No entities to identify)';
152
  LNG_STATUS_NOTAVAIL_NO_ENTITIES         = 'Not available (No entities to identify)';
150
  LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)';
153
  LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)';
151
  LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC = 'Not available (Arguments required)';
154
  LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC = 'Not available (Arguments required)';
-
 
155
  LNG_STATUS_NOTAVAIL_INVALID_INPUT       = 'Not available (Plugin received invalid input)';
152
  LNG_UNKNOWN_NOTAVAIL                    = 'Not available (Unknown status code %s)';
156
  LNG_UNKNOWN_NOTAVAIL                    = 'Not available (Unknown status code %s)';
153
 
157
 
154
  LNG_STATUS_FAILURE_UNSPECIFIED          = 'Error (Unspecified)';
158
  LNG_STATUS_FAILURE_UNSPECIFIED          = 'Error (Unspecified)';
155
  LNG_STATUS_FAILURE_BUFFER_TOO_SMALL     = 'Error (The provided buffer is too small!)';
159
  LNG_STATUS_FAILURE_BUFFER_TOO_SMALL     = 'Error (The provided buffer is too small!)';
156
  LNG_STATUS_FAILURE_INVALID_ARGS         = 'Error (The function received invalid arguments!)';
160
  LNG_STATUS_FAILURE_INVALID_ARGS         = 'Error (An internal function received invalid arguments!)';
157
  LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED  = 'Error (The plugin is not licensed)';
161
  LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED  = 'Error (The plugin is not licensed)';
158
  LNG_STATUS_FAILURE_NO_RETURNED_VALUE    = 'Error (Plugin did not return a status)';
162
  LNG_STATUS_FAILURE_NO_RETURNED_VALUE    = 'Error (Plugin did not return a status)';
159
  LNG_STATUS_FAILURE_CATCHED_EXCEPTION    = 'Error (Catched unexpected Exception)';
163
  LNG_STATUS_FAILURE_CATCHED_EXCEPTION    = 'Error (Catched unexpected Exception)';
160
  LNG_UNKNOWN_FAILED                      = 'Error (Unknown status code %s)';
164
  LNG_UNKNOWN_FAILED                      = 'Error (Unknown status code %s)';
161
 
165
 
Line 169... Line 173...
169
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false)    then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED
173
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false)    then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED
170
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false)    then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED
174
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false)    then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED
171
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false)         then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES
175
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false)         then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES
172
  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)])
176
  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)])
173
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC, false) then result := LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC
177
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC, false) then result := LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC
-
 
178
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_INVALID_INPUT, false)       then result := LNG_STATUS_NOTAVAIL_INVALID_INPUT
174
 
179
 
175
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false)          then result := LNG_STATUS_FAILURE_UNSPECIFIED
180
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false)          then result := LNG_STATUS_FAILURE_UNSPECIFIED
176
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false)     then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL
181
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false)     then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL
177
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false)         then result := LNG_STATUS_FAILURE_INVALID_ARGS
182
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false)         then result := LNG_STATUS_FAILURE_INVALID_ARGS
178
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false)  then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED
183
  else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false)  then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED
Line 211... Line 216...
211
begin
216
begin
212
  inherited Create;
217
  inherited Create;
213
  FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true);
218
  FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true);
214
end;
219
end;
215
 
220
 
216
function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; var outIDs: TArrayOfString): boolean;
221
function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean;
217
var
222
var
218
  ude: TUD2IdentificationEntry;
223
  ude: TUD2IdentificationEntry;
219
  i: integer;
224
  i: integer;
220
  id: string;
225
  id: string;
221
  l: integer;
226
  l: integer;
Line 236... Line 241...
236
  end;
241
  end;
237
 
242
 
238
  // The dynamic content was already evaluated (and therefore is already added in FDetectedIdentifications).
243
  // The dynamic content was already evaluated (and therefore is already added in FDetectedIdentifications).
239
  if Length(outIDs) > 0 then exit;
244
  if Length(outIDs) > 0 then exit;
240
 
245
 
241
  outIDs := GetDynamicRequestResult(dynamicData);
246
  outIDs := GetDynamicRequestResult(dynamicData, AErrorOut);
242
 
247
 
243
  for i := 0 to Length(outIDs)-1 do
248
  for i := 0 to Length(outIDs)-1 do
244
  begin
249
  begin
245
    id := outIDs[i];
250
    id := outIDs[i];
246
 
251
 
Line 250... Line 255...
250
 
255
 
251
    result := true;
256
    result := true;
252
  end;
257
  end;
253
end;
258
end;
254
 
259
 
255
function TUD2Plugin.GetDynamicRequestResult(dynamicData: WideString): TArrayOfString;
260
function TUD2Plugin.GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString;
256
var
261
var
257
  lngID: LANGID;
262
  lngID: LANGID;
258
  pll: TUD2PluginLoader;
263
  loader: TUD2PluginLoader;
259
begin
264
begin
260
  lngID := GetSystemDefaultLangID;
265
  lngID := GetSystemDefaultLangID;
261
 
266
 
262
  pll := TUD2PluginLoader.Create(false, PluginDLL, lngid, true, dynamicData);
267
  loader := TUD2PluginLoader.Create(false, PluginDLL, lngid, true, dynamicData);
263
  try
268
  try
264
    pll.WaitFor;
269
    loader.WaitFor;
265
    result := pll.ResultIdentifiers;
270
    result := loader.ResultIdentifiers;
266
    if Assigned(pll.pl) then FreeAndNil(pll.pl);
271
    if Assigned(AErrorOut) then
-
 
272
    begin
-
 
273
      AErrorOut.AddStrings(loader.Errors);
-
 
274
    end;
-
 
275
 
-
 
276
    // TODO: Use assign() instead? or allow TUD2PluginLoader to write the TPlugin object directly?
-
 
277
    //       Should we even overwrite the current plugin data, or return the new plugin?
-
 
278
    FIdentificationProcedureStatusCode := loader.plugin.IdentificationProcedureStatusCode;
-
 
279
    FIdentificationProcedureStatusCodeDescribed := loader.plugin.IdentificationProcedureStatusCodeDescribed;
-
 
280
    FOSNotSupportedEnforced := loader.plugin.OSNotSupportedEnforced;
-
 
281
    FLoadingTime := loader.Plugin.LoadingTime;
-
 
282
 
267
  finally
283
  finally
-
 
284
    if Assigned(loader.Plugin) then FreeAndNil(loader.Plugin);
268
    pll.Free;
285
    loader.Free;
269
  end;
286
  end;
270
end;
287
end;
271
 
288
 
272
function TUD2Plugin.EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean;
289
function TUD2Plugin.EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean;
273
begin
290
begin
274
  result := SameText(IdentificationMethodName, idMethodNameOrGUID) or
291
  result := SameText(IdentificationMethodName, idMethodNameOrGUID) or
275
            SameText(GUIDToString(PluginGUID), idMethodNameOrGUID)
292
            SameText(GUIDToString(PluginGUID), idMethodNameOrGUID)
276
end;
293
end;
277
 
294
 
278
function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString): boolean;
295
function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean;
279
var
296
var
280
  dummy: TArrayOfString;
297
  dummy: TArrayOfString;
281
begin
298
begin
282
  result := InvokeDynamicCheck(dynamicData, dummy)
299
  result := InvokeDynamicCheck(dynamicData, AErrorOut, dummy)
283
end;
300
end;
284
 
301
 
285
{ TUD2IdentificationEntry }
302
{ TUD2IdentificationEntry }
286
 
303
 
287
procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings);
304
procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings);
Line 300... Line 317...
300
 
317
 
301
constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString;
318
constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString;
302
  APlugin: TUD2Plugin);
319
  APlugin: TUD2Plugin);
303
begin
320
begin
304
  inherited Create;
321
  inherited Create;
-
 
322
 
-
 
323
  // TODO: We need to do this, because ReadSectionValues strips the names of the name-value pairs...
-
 
324
  //       We should correct ReadSectionValues...
-
 
325
  // Example: DriveSerial(c:):2SHSWNHA010807 X    =calc.exe
-
 
326
  // ReadSectionValues will return "DriveSerial(c:):2SHSWNHA010807 X=calc.exe"
-
 
327
  AIdentificationString := Trim(AIdentificationString);
-
 
328
 
305
  FIdentificationString := AIdentificationString;
329
  FIdentificationString := AIdentificationString;
306
  FPlugin := APlugin;
330
  FPlugin := APlugin;
307
end;
331
end;
308
 
332
 
309
{ TUD2 }
333
{ TUD2 }
Line 352... Line 376...
352
    for i := 0 to tob.count-1 do
376
    for i := 0 to tob.count-1 do
353
    begin
377
    begin
354
      pluginLoader := tob.items[i] as TUD2PluginLoader;
378
      pluginLoader := tob.items[i] as TUD2PluginLoader;
355
      pluginLoader.WaitFor;
379
      pluginLoader.WaitFor;
356
      Errors.AddStrings(pluginLoader.Errors);
380
      Errors.AddStrings(pluginLoader.Errors);
357
      if Assigned(pluginLoader.pl) then
381
      if Assigned(pluginLoader.Plugin) then
358
      begin
382
      begin
359
        {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
383
        {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
360
        if pluginLoader.pl.PluginGUIDSet then
384
        if pluginLoader.Plugin.PluginGUIDSet then
361
        begin
385
        begin
362
          sPluginID := GUIDToString(pluginLoader.pl.PluginGUID);
386
          sPluginID := GUIDToString(pluginLoader.Plugin.PluginGUID);
363
          prevDLL := FGUIDLookup.Values[sPluginID];
387
          prevDLL := FGUIDLookup.Values[sPluginID];
364
          if (prevDLL <> '') and (prevDLL <> pluginLoader.pl.PluginDLL) then
388
          if (prevDLL <> '') and (prevDLL <> pluginLoader.Plugin.PluginDLL) then
365
          begin
389
          begin
366
            Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.pl.PluginDLL]));
390
            Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.Plugin.PluginDLL]));
367
            pluginLoader.pl.Free;
391
            pluginLoader.Plugin.Free;
368
          end
392
          end
369
          else
393
          else
370
          begin
394
          begin
371
            FGUIDLookup.Values[sPluginID] := pluginLoader.pl.PluginDLL;
395
            FGUIDLookup.Values[sPluginID] := pluginLoader.Plugin.PluginDLL;
372
            LoadedPlugins.Add(pluginLoader.pl);
396
            LoadedPlugins.Add(pluginLoader.Plugin);
373
          end;
397
          end;
374
        end
398
        end
375
        else
399
        else
376
        begin
400
        begin
377
          LoadedPlugins.Add(pluginLoader.pl);
401
          LoadedPlugins.Add(pluginLoader.Plugin);
378
        end;
402
        end;
379
        {$ELSE}
403
        {$ELSE}
380
        LoadedPlugins.Add(pluginLoader.pl);
404
        LoadedPlugins.Add(pluginLoader.Plugin);
381
        {$ENDIF}
405
        {$ENDIF}
382
      end;
406
      end;
383
      pluginLoader.Free;
407
      pluginLoader.Free;
384
    end;
408
    end;
385
  finally
409
  finally
Line 410... Line 434...
410
 
434
 
411
function TUD2.GetTaskName(AShortTaskName: string): string;
435
function TUD2.GetTaskName(AShortTaskName: string): string;
412
resourcestring
436
resourcestring
413
  LNG_NO_DESCRIPTION = '(%s)';
437
  LNG_NO_DESCRIPTION = '(%s)';
414
begin
438
begin
415
  result := FIniFile.ReadString(AShortTaskName, 'Description', Format(LNG_NO_DESCRIPTION, [AShortTaskName]));
439
  result := FIniFile.ReadString(AShortTaskName, UD2_TagDescription, Format(LNG_NO_DESCRIPTION, [AShortTaskName]));
416
end;
440
end;
417
 
441
 
418
procedure TUD2.GetTaskListing(outSL: TStrings);
442
procedure TUD2.GetTaskListing(outSL: TStrings);
419
var
443
var
420
  sl: TStringList;
444
  sl: TStringList;
Line 479... Line 503...
479
      ude.GetIdNames(outSL);
503
      ude.GetIdNames(outSL);
480
    end;
504
    end;
481
  end;
505
  end;
482
end;
506
end;
483
 
507
 
484
function TUD2.FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil): boolean;
508
function TUD2.FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean;
485
begin
509
begin
486
  result := FulfilsEverySubterm(UD2_CondsToStr(conds), slIdNames);
510
  result := FulfilsEverySubterm(UD2_CondsToStr(conds), slIdNames, AErrorOut);
487
end;
511
end;
488
 
512
 
489
function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean;
513
function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean;
490
var
514
var
491
  i: integer;
515
  i: integer;
492
  p: TUD2Plugin;
516
  p: TUD2Plugin;
493
  cleanUpStringList: boolean;
517
  cleanUpStringList: boolean;
494
  conds: TUD2TDFConditionArray;
518
  conds: TUD2TDFConditionArray;
495
  cond: TUD2TDFCondition;
519
  cond: TUD2TDFCondition;
496
  idName: string;
520
  idName: string;
497
begin
521
begin
-
 
522
  {$IFDEF NO_CONDITIONS_IS_FAILURE}
-
 
523
  if idTerm = '' then
-
 
524
  begin
-
 
525
    SetLength(conds, 0);
-
 
526
    result := false;
-
 
527
    Exit;
-
 
528
  end;
-
 
529
  {$ENDIF}
-
 
530
 
498
  cleanUpStringList := slIdNames = nil;
531
  cleanUpStringList := slIdNames = nil;
499
  try
532
  try
500
    if cleanUpStringList then
533
    if cleanUpStringList then
501
    begin
534
    begin
502
      slIdNames := TStringList.Create;
535
      slIdNames := TStringList.Create;
Line 513... Line 546...
513
      if cond.dynamicDataUsed then
546
      if cond.dynamicDataUsed then
514
      begin
547
      begin
515
        p := FindPluginByMethodNameOrGuid(cond.idMethodName);
548
        p := FindPluginByMethodNameOrGuid(cond.idMethodName);
516
        if Assigned(p) then
549
        if Assigned(p) then
517
        begin
550
        begin
518
          if p.InvokeDynamicCheck(cond.dynamicData) then
551
          if p.InvokeDynamicCheck(cond.dynamicData, AErrorOut) then
519
          begin
552
          begin
520
            // Reload the identifications
553
            // Reload the identifications
521
            slIdNames.Clear;
554
            slIdNames.Clear;
522
            GetAllDetectedIDs(slIdNames);
555
            GetAllDetectedIDs(slIdNames);
523
          end;
556
          end;
Line 555... Line 588...
555
      Exit;
588
      Exit;
556
    end;
589
    end;
557
  end;
590
  end;
558
end;
591
end;
559
 
592
 
560
function TUD2.GetCommandList(ShortTaskName: string): TUD2CommandArray;
593
function TUD2.GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray;
561
var
594
var
562
  i, j, l: integer;
595
  i, j, l: integer;
563
  slSV, slIdNames: TStrings;
596
  slSV, slIdNames: TStrings;
564
  tmpCmds: TUD2CommandArray;
597
  tmpCmds: TUD2CommandArray;
565
begin
598
begin
Line 573... Line 606...
573
    slSV := TStringList.Create;
606
    slSV := TStringList.Create;
574
    try
607
    try
575
      FIniFile.ReadSectionValues(ShortTaskName, slSV);
608
      FIniFile.ReadSectionValues(ShortTaskName, slSV);
576
      for i := 0 to slSV.Count-1 do
609
      for i := 0 to slSV.Count-1 do
577
      begin
610
      begin
578
        tmpCmds := CheckTerm(slSV.Strings[i], slIdNames);
611
        tmpCmds := CheckTerm(slSV.Strings[i], slIdNames, AErrorOut);
579
        for j := Low(tmpCmds) to High(tmpCmds) do
612
        for j := Low(tmpCmds) to High(tmpCmds) do
580
        begin
613
        begin
581
          l := Length(result);
614
          l := Length(result);
582
          SetLength(result, l+1);
615
          SetLength(result, l+1);
583
          result[l] := tmpCmds[j];
616
          result[l] := tmpCmds[j];
Line 589... Line 622...
589
  finally
622
  finally
590
    slIdNames.Free;
623
    slIdNames.Free;
591
  end;
624
  end;
592
end;
625
end;
593
 
626
 
594
function TUD2.CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil): TUD2CommandArray;
627
function TUD2.CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray;
595
var
628
var
596
  slIdNamesCreated: boolean;
629
  slIdNamesCreated: boolean;
597
  ent: TUD2TDFEntry;
630
  ent: TUD2TDFEntry;
598
begin
631
begin
599
  SetLength(result, 0);
632
  SetLength(result, 0);
Line 606... Line 639...
606
      slIdNames := TStringList.Create;
639
      slIdNames := TStringList.Create;
607
      GetAllDetectedIDs(slIdNames);
640
      GetAllDetectedIDs(slIdNames);
608
    end;
641
    end;
609
 
642
 
610
    if not UD2P_ParseTdfLine(idTermAndCmd, ent) then Exit;
643
    if not UD2P_ParseTdfLine(idTermAndCmd, ent) then Exit;
611
    if FulfilsEverySubterm(ent.ids, slIdNames) then
644
    if FulfilsEverySubterm(ent.ids, slIdNames, AErrorOut) then
612
    begin
645
    begin
613
      result := ent.commands;
646
      result := ent.commands;
614
    end;
647
    end;
615
  finally
648
  finally
616
    if slIdNamesCreated then slIdNames.Free;
649
    if slIdNamesCreated then slIdNames.Free;
Line 628... Line 661...
628
 
661
 
629
constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString);
662
constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString);
630
begin
663
begin
631
  inherited Create(Suspended);
664
  inherited Create(Suspended);
632
  dllfile := dll;
665
  dllfile := dll;
633
  pl := nil;
666
  Plugin := nil;
634
  Errors := TStringList.Create;
667
  Errors := TStringList.Create;
635
  lngid := alngid;
668
  lngid := alngid;
636
  self.useDynamicData := useDynamicData;
669
  self.useDynamicData := useDynamicData;
637
  Self.dynamicData := dynamicData;
670
  Self.dynamicData := dynamicData;
638
end;
671
end;
Line 696... Line 729...
696
      iniConfig := TIniFile.Create(sPluginConfigFile);
729
      iniConfig := TIniFile.Create(sPluginConfigFile);
697
      try
730
      try
698
        sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', '');
731
        sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', '');
699
        if sOverrideGUID <> '' then
732
        if sOverrideGUID <> '' then
700
        begin
733
        begin
701
          pl.FPluginGUIDSet := true;
734
          Plugin.FPluginGUIDSet := true;
702
          pl.FPluginGUID := StringToGUID(sOverrideGUID);
735
          Plugin.FPluginGUID := StringToGUID(sOverrideGUID);
703
          result := true;
736
          result := true;
704
        end;
737
        end;
705
      finally
738
      finally
706
        iniConfig.Free;
739
        iniConfig.Free;
707
      end;
740
      end;
Line 726... Line 759...
726
    end;
759
    end;
727
  end;
760
  end;
728
 
761
 
729
  procedure _OverwriteStatusToOSNotSupported;
762
  procedure _OverwriteStatusToOSNotSupported;
730
  begin
763
  begin
731
    pl := TUD2Plugin.Create;
764
    Plugin := TUD2Plugin.Create;
732
    pl.FPluginDLL := dllFile;
765
    Plugin.FPluginDLL := dllFile;
733
    statusCode := UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED;
766
    statusCode := UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED;
734
    pl.FIdentificationProcedureStatusCode := statusCode;
767
    Plugin.FIdentificationProcedureStatusCode := statusCode;
735
    pl.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode);
768
    Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode);
736
    pl.FOSNotSupportedEnforced := true;
769
    Plugin.FOSNotSupportedEnforced := true;
737
    result := true;
770
    result := true;
738
  end;
771
  end;
739
 
772
 
740
resourcestring
773
resourcestring
741
  LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded: %s';
774
  LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded: %s';
Line 778... Line 811...
778
        begin
811
        begin
779
          Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile]));
812
          Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile]));
780
          Exit;
813
          Exit;
781
        end;
814
        end;
782
 
815
 
783
        pl := TUD2Plugin.Create;
816
        Plugin := TUD2Plugin.Create;
784
        pl.FPluginDLL := dllFile;
817
        Plugin.FPluginDLL := dllFile;
785
 
818
 
786
        @fDynamicIdentificationStringW := GetProcAddress(dllHandle, mnDynamicIdentificationStringW);
819
        @fDynamicIdentificationStringW := GetProcAddress(dllHandle, mnDynamicIdentificationStringW);
787
        pl.FAcceptsDynamicRequests := Assigned(fDynamicIdentificationStringW);
820
        Plugin.FAcceptsDynamicRequests := Assigned(fDynamicIdentificationStringW);
788
 
821
 
789
        fIdentificationStringW := nil;
822
        fIdentificationStringW := nil;
790
        if useDynamicData then
823
        if useDynamicData then
791
        begin
824
        begin
792
          if not pl.AcceptsDynamicRequests then
825
          if not Plugin.AcceptsDynamicRequests then
793
          begin
826
          begin
794
            // TODO xxx: Darf hier ein fataler Fehler entstehen, obwohl dieses Szenario nur durch die INI file auftreten kann?
827
            // TODO xxx: Darf hier ein fataler Fehler entstehen, obwohl dieses Szenario nur durch die INI file auftreten kann?
795
            // TODO (allgemein): doku
828
            // TODO (allgemein): doku
796
            Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile]));
829
            Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile]));
797
            Exit;
830
            Exit;
Line 855... Line 888...
855
          if not Assigned(fPluginIdentifier) then
888
          if not Assigned(fPluginIdentifier) then
856
          begin
889
          begin
857
            Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile]));
890
            Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile]));
858
            Exit;
891
            Exit;
859
          end;
892
          end;
860
          pl.FPluginGUIDSet := true;
893
          Plugin.FPluginGUIDSet := true;
861
          pl.FPluginGUID := fPluginIdentifier();
894
          Plugin.FPluginGUID := fPluginIdentifier();
862
        end;
895
        end;
863
 
896
 
864
        statusCode := fCheckLicense(nil);
897
        statusCode := fCheckLicense(nil);
865
        if statusCode.wCategory = UD2_STATUSCAT_FAILED then
898
        if statusCode.wCategory = UD2_STATUSCAT_FAILED then
866
        begin
899
        begin
Line 868... Line 901...
868
          Exit;
901
          Exit;
869
        end;
902
        end;
870
 
903
 
871
        ZeroMemory(@buf, cchBufferSize);
904
        ZeroMemory(@buf, cchBufferSize);
872
        statusCode := fPluginNameW(@buf, cchBufferSize, lngID);
905
        statusCode := fPluginNameW(@buf, cchBufferSize, lngID);
873
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then pl.FPluginName := PWideChar(@buf)
906
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then Plugin.FPluginName := PWideChar(@buf)
874
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.FPluginName := ''
907
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginName := ''
875
        else
908
        else
876
        begin
909
        begin
877
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile]));
910
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile]));
878
          Exit;
911
          Exit;
879
        end;
912
        end;
880
 
913
 
881
        ZeroMemory(@buf, cchBufferSize);
914
        ZeroMemory(@buf, cchBufferSize);
882
        statusCode := fPluginVendorW(@buf, cchBufferSize, lngID);
915
        statusCode := fPluginVendorW(@buf, cchBufferSize, lngID);
883
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then pl.FPluginVendor := PWideChar(@buf)
916
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then Plugin.FPluginVendor := PWideChar(@buf)
884
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.FPluginVendor := ''
917
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVendor := ''
885
        else
918
        else
886
        begin
919
        begin
887
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile]));
920
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile]));
888
          Exit;
921
          Exit;
889
        end;
922
        end;
890
 
923
 
891
        ZeroMemory(@buf, cchBufferSize);
924
        ZeroMemory(@buf, cchBufferSize);
892
        statusCode := fPluginVersionW(@buf, cchBufferSize, lngID);
925
        statusCode := fPluginVersionW(@buf, cchBufferSize, lngID);
893
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then pl.FPluginVersion := PWideChar(@buf)
926
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then Plugin.FPluginVersion := PWideChar(@buf)
894
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.FPluginVersion := ''
927
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVersion := ''
895
        else
928
        else
896
        begin
929
        begin
897
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile]));
930
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile]));
898
          Exit;
931
          Exit;
899
        end;
932
        end;
900
 
933
 
901
        ZeroMemory(@buf, cchBufferSize);
934
        ZeroMemory(@buf, cchBufferSize);
902
        statusCode := fIdentificationMethodNameW(@buf, cchBufferSize);
935
        statusCode := fIdentificationMethodNameW(@buf, cchBufferSize);
903
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then pl.FIdentificationMethodName := PWideChar(@buf)
936
             if statusCode.wCategory = UD2_STATUSCAT_SUCCESS   then Plugin.FIdentificationMethodName := PWideChar(@buf)
904
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.FIdentificationMethodName := ''
937
        else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FIdentificationMethodName := ''
905
        else
938
        else
906
        begin
939
        begin
907
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile]));
940
          Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile]));
908
          Exit;
941
          Exit;
909
        end;
942
        end;
Line 916... Line 949...
916
        end
949
        end
917
        else
950
        else
918
        begin
951
        begin
919
          statusCode := fIdentificationStringW(@buf, cchBufferSize);
952
          statusCode := fIdentificationStringW(@buf, cchBufferSize);
920
        end;
953
        end;
921
        pl.FIdentificationProcedureStatusCode := statusCode;
954
        Plugin.FIdentificationProcedureStatusCode := statusCode;
922
        pl.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode);
955
        Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode);
923
        if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then
956
        if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then
924
        begin
957
        begin
925
          sIdentifier := PWideChar(@buf);
958
          sIdentifier := PWideChar(@buf);
926
          if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then
959
          if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then
927
          begin
960
          begin
928
            // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER)
961
            // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER)
929
            SetLength(ResultIdentifiers, 0);
962
            SetLength(ResultIdentifiers, 0);
930
            ResultIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier);
963
            ResultIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier);
931
            for i := Low(ResultIdentifiers) to High(ResultIdentifiers) do
964
            for i := Low(ResultIdentifiers) to High(ResultIdentifiers) do
932
            begin
965
            begin
933
              pl.AddIdentification(ResultIdentifiers[i]);
966
              Plugin.AddIdentification(ResultIdentifiers[i]);
934
            end;
967
            end;
935
          end
968
          end
936
          else
969
          else
937
          begin
970
          begin
938
            pl.AddIdentification(sIdentifier);
971
            Plugin.AddIdentification(sIdentifier);
939
 
972
 
940
            SetLength(ResultIdentifiers, 1);
973
            SetLength(ResultIdentifiers, 1);
941
            ResultIdentifiers[0] := sIdentifier;
974
            ResultIdentifiers[0] := sIdentifier;
942
          end;
975
          end;
943
        end
976
        end
Line 948... Line 981...
948
            _OverwriteStatusToOSNotSupported;
981
            _OverwriteStatusToOSNotSupported;
949
            Exit;
982
            Exit;
950
          end;
983
          end;
951
 
984
 
952
          // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile]));
985
          // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile]));
953
          Errors.Add(Format(LNG_METHOD_FAILURE, [pl.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile]));
986
          Errors.Add(Format(LNG_METHOD_FAILURE, [Plugin.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile]));
954
          Exit;
987
          Exit;
955
        end;
988
        end;
956
 
989
 
957
        result := true;
990
        result := true;
958
      finally
991
      finally
959
        if not result and Assigned(pl) then FreeAndNil(pl);
992
        if not result and Assigned(Plugin) then FreeAndNil(Plugin);
960
        FreeLibrary(dllHandle);
993
        FreeLibrary(dllHandle);
961
      end;
994
      end;
962
    finally
995
    finally
963
      UD2_SetThreadErrorMode(bakErrorMode, nil);
996
      UD2_SetThreadErrorMode(bakErrorMode, nil);
964
 
997
 
965
      if result then
998
      if result then
966
      begin
999
      begin
967
        endtime := GetTickCount;
1000
        endtime := GetTickCount;
968
        time := endtime - starttime;
1001
        time := endtime - starttime;
969
        if endtime < starttime then time := High(Cardinal) - time;
1002
        if endtime < starttime then time := High(Cardinal) - time;
970
        pl.FLoadingTime := time;
1003
        Plugin.FLoadingTime := time;
971
      end;
1004
      end;
972
    end;
1005
    end;
973
  except
1006
  except
974
    // TODO: when an exception happens in a cdecl DLL, then this code is somehow not
1007
    // TODO: when an exception happens in a cdecl DLL, then this code is somehow not
975
    // executed. Probably the memory is corrupted. Anyway, a cdecl DLL shall NEVER
1008
    // executed. Probably the memory is corrupted. Anyway, a cdecl DLL shall NEVER