Subversion Repositories userdetect2

Rev

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

Rev 69 Rev 70
Line 4... Line 4...
4
 
4
 
5
{$IF CompilerVersion >= 25.0}
5
{$IF CompilerVersion >= 25.0}
6
{$LEGACYIFEND ON}
6
{$LEGACYIFEND ON}
7
{$IFEND}
7
{$IFEND}
8
 
8
 
-
 
9
{$INCLUDE 'UserDetect2.inc'}
-
 
10
 
9
uses
11
uses
10
  Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs;
12
  Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf;
11
 
13
 
12
const
14
const
13
  cchBufferSize = 32768;
15
  cchBufferSize = 32768;
14
 
16
 
15
type
17
type
Line 21... Line 23...
21
    PluginGUID: TGUID;
23
    PluginGUID: TGUID;
22
    PluginName: WideString;
24
    PluginName: WideString;
23
    PluginVendor: WideString;
25
    PluginVendor: WideString;
24
    PluginVersion: WideString;
26
    PluginVersion: WideString;
25
    IdentificationMethodName: WideString;
27
    IdentificationMethodName: WideString;
-
 
28
 
-
 
29
    // ONLY contains the non-failure status code of IdentificationStringW
-
 
30
    IdentificationProcedureStatusCode: UD2_STATUS;
-
 
31
    IdentificationProcedureStatusCodeDescribed: WideString;
-
 
32
   
26
    Time: Cardinal;
33
    Time: Cardinal;
27
    function PluginGUIDString: string;
34
    function PluginGUIDString: string;
28
    property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}
35
    property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}
29
      read FDetectedIdentifications;
36
      read FDetectedIdentifications;
30
    destructor Destroy; override;
37
    destructor Destroy; override;
Line 44... Line 51...
44
    constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin);
51
    constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin);
45
  end;
52
  end;
46
 
53
 
47
  TUD2 = class(TObject)
54
  TUD2 = class(TObject)
48
  private
55
  private
-
 
56
    {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
49
    FGUIDLookup: TStrings;
57
    FGUIDLookup: TStrings;
-
 
58
    {$ENDIF}
50
  protected
59
  protected
51
    FLoadedPlugins: TObjectList{<TUD2Plugin>};
60
    FLoadedPlugins: TObjectList{<TUD2Plugin>};
52
    FIniFile: TMemIniFile;
61
    FIniFile: TMemIniFile;
53
    FErrors: TStrings;
62
    FErrors: TStrings;
54
    FIniFileName: string;
63
    FIniFileName: string;
Line 66... Line 75...
66
    function ReadMetatagString(ShortTaskName, MetatagName: string;
75
    function ReadMetatagString(ShortTaskName, MetatagName: string;
67
      DefaultVal: string): string;
76
      DefaultVal: string): string;
68
    function ReadMetatagBool(ShortTaskName, MetatagName: string;
77
    function ReadMetatagBool(ShortTaskName, MetatagName: string;
69
      DefaultVal: string): boolean;
78
      DefaultVal: string): boolean;
70
    function GetTaskName(AShortTaskName: string): string;
79
    function GetTaskName(AShortTaskName: string): string;
-
 
80
    class function GenericErrorLookup(dwStatus: UD2_STATUS): string;
71
  end;
81
  end;
72
 
82
 
73
implementation
83
implementation
74
 
84
 
75
uses
85
uses
76
  UD2_PluginIntf, UD2_Utils;
86
  UD2_Utils;
77
 
87
 
78
type
88
type
79
  TUD2PluginLoader = class(TThread)
89
  TUD2PluginLoader = class(TThread)
80
  protected
90
  protected
81
    dllFile: string;
91
    dllFile: string;
82
    lngID: LANGID;
92
    lngID: LANGID;
83
    procedure Execute; override;
93
    procedure Execute; override;
84
    procedure HandleDLL;
94
    function HandleDLL: boolean;
85
  public
95
  public
86
    pl: TUD2Plugin;
96
    pl: TUD2Plugin;
87
    Errors: TStringList;
97
    Errors: TStringList;
88
    constructor Create(Suspended: boolean; DLL: string; alngid: LANGID);
98
    constructor Create(Suspended: boolean; DLL: string; alngid: LANGID);
89
    destructor Destroy; override;
99
    destructor Destroy; override;
90
  end;
100
  end;
91
 
101
 
92
function UD2_ErrorLookup(dwStatus: UD2_STATUS): string;
102
class function TUD2.GenericErrorLookup(dwStatus: UD2_STATUS): string;
93
resourcestring
103
resourcestring
94
  LNG_STATUS_OK_UNSPECIFIED            = 'Unspecified generic success';
104
  LNG_STATUS_OK_UNSPECIFIED            = 'Unspecified generic success';
95
  LNG_STATUS_OK_SINGLELINE             = 'Operation successful; one identifier returned';
105
  LNG_STATUS_OK_SINGLELINE             = 'Operation successful; one identifier returned';
96
  LNG_STATUS_OK_MULTILINE              = 'Operation successful; multiple identifiers returned';
106
  LNG_STATUS_OK_MULTILINE              = 'Operation successful; multiple identifiers returned';
97
 
107
 
Line 184... Line 194...
184
 
194
 
185
procedure TUD2.HandlePluginDir(APluginDir: string);
195
procedure TUD2.HandlePluginDir(APluginDir: string);
186
Var
196
Var
187
  SR: TSearchRec;
197
  SR: TSearchRec;
188
  path: string;
198
  path: string;
189
  x: TUD2PluginLoader;
199
  pluginLoader: TUD2PluginLoader;
190
  tob: TObjectList;
200
  tob: TObjectList;
191
  i: integer;
201
  i: integer;
-
 
202
  {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
192
  sPluginID, v: string;
203
  sPluginID, prevDLL: string;
-
 
204
  {$ENDIF}
193
  lngid: LANGID;
205
  lngid: LANGID;
194
resourcestring
206
resourcestring
195
  LNG_PLUGINS_SAME_GUID = 'Attention: The plugin "%s" and the plugin "%s" have the same identification GUID. The latter will not be loaded.';
207
  LNG_PLUGINS_SAME_GUID = 'Attention: The plugin "%s" and the plugin "%s" have the same identification GUID. The latter will not be loaded.';
196
begin
208
begin
197
  tob := TObjectList.Create;
209
  tob := TObjectList.Create;
Line 219... Line 231...
219
      end;
231
      end;
220
    end;
232
    end;
221
 
233
 
222
    for i := 0 to tob.count-1 do
234
    for i := 0 to tob.count-1 do
223
    begin
235
    begin
224
      x := tob.items[i] as TUD2PluginLoader;
236
      pluginLoader := tob.items[i] as TUD2PluginLoader;
225
      x.WaitFor;
237
      pluginLoader.WaitFor;
226
      Errors.AddStrings(x.Errors);
238
      Errors.AddStrings(pluginLoader.Errors);
-
 
239
      {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
227
      if Assigned(x.pl) then
240
      if Assigned(pluginLoader.pl) then
228
      begin
241
      begin
229
        sPluginID := GUIDToString(x.pl.PluginGUID);
242
        sPluginID := GUIDToString(pluginLoader.pl.PluginGUID);
230
        v := FGUIDLookup.Values[sPluginID];
243
        prevDLL := FGUIDLookup.Values[sPluginID];
231
        if (v <> '') and (v <> x.pl.PluginDLL) then
244
        if (prevDLL <> '') and (prevDLL <> pluginLoader.pl.PluginDLL) then
232
        begin
245
        begin
233
          Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [v, x.pl.PluginDLL]));
246
          Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.pl.PluginDLL]));
234
          x.pl.Free;
247
          pluginLoader.pl.Free;
235
        end
248
        end
236
        else
249
        else
237
        begin
250
        begin
238
          FGUIDLookup.Values[sPluginID] := x.pl.PluginDLL;
251
          FGUIDLookup.Values[sPluginID] := pluginLoader.pl.PluginDLL;
239
          LoadedPlugins.Add(x.pl);
252
          LoadedPlugins.Add(pluginLoader.pl);
240
        end;
253
        end;
241
      end;
254
      end;
242
      x.Free;
255
      {$ENDIF}
-
 
256
      pluginLoader.Free;
243
    end;
257
    end;
244
  finally
258
  finally
245
    tob.free;
259
    tob.free;
246
  end;
260
  end;
247
end;
261
end;
248
 
262
 
249
destructor TUD2.Destroy;
263
destructor TUD2.Destroy;
250
begin
264
begin
251
  FIniFile.Free;
265
  FIniFile.Free;
252
  FLoadedPlugins.Free;
266
  FLoadedPlugins.Free;
-
 
267
  {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
253
  FGUIDLookup.Free;
268
  FGUIDLookup.Free;
-
 
269
  {$ENDIF}
254
  FErrors.Free;
270
  FErrors.Free;
255
end;
271
end;
256
 
272
 
257
constructor TUD2.Create(AIniFileName: string);
273
constructor TUD2.Create(AIniFileName: string);
258
begin
274
begin
259
  FIniFileName := AIniFileName;
275
  FIniFileName := AIniFileName;
260
  FLoadedPlugins := TObjectList{<TUD2Plugin>}.Create(true);
276
  FLoadedPlugins := TObjectList{<TUD2Plugin>}.Create(true);
261
  FIniFile := TMemIniFile.Create(IniFileName);
277
  FIniFile := TMemIniFile.Create(IniFileName);
-
 
278
  {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID}
262
  FGUIDLookup := TStringList.Create;
279
  FGUIDLookup := TStringList.Create;
-
 
280
  {$ENDIF}
263
  FErrors := TStringList.Create;
281
  FErrors := TStringList.Create;
264
end;
282
end;
265
 
283
 
266
function TUD2.GetTaskName(AShortTaskName: string): string;
284
function TUD2.GetTaskName(AShortTaskName: string): string;
267
resourcestring
285
resourcestring
Line 405... Line 423...
405
begin
423
begin
406
  Errors.Free;
424
  Errors.Free;
407
  inherited;
425
  inherited;
408
end;
426
end;
409
 
427
 
410
procedure TUD2PluginLoader.HandleDLL;
428
function TUD2PluginLoader.HandleDLL: boolean;
411
var
429
var
412
  sIdentifier: WideString;
430
  sIdentifier: WideString;
413
  sIdentifiers: TArrayOfString;
431
  sIdentifiers: TArrayOfString;
414
  buf: array[0..cchBufferSize-1] of WideChar;
432
  buf: array[0..cchBufferSize-1] of WideChar;
415
  sPluginConfigFile: string;
433
  sPluginConfigFile: string;
416
  iniConfig: TINIFile;
434
  iniConfig: TINIFile;
417
  sOverrideGUID: string;
435
  sOverrideGUID: string;
418
  pluginIDfound: boolean;
436
  pluginIDfound: boolean;
419
  pluginInterfaceID: TGUID;
437
  pluginInterfaceID: TGUID;
420
  dllHandle: cardinal;
438
  dllHandle: Cardinal;
421
  fPluginInterfaceID: TFuncPluginInterfaceID;
439
  fPluginInterfaceID: TFuncPluginInterfaceID;
422
  fPluginIdentifier: TFuncPluginIdentifier;
440
  fPluginIdentifier: TFuncPluginIdentifier;
423
  fPluginNameW: TFuncPluginNameW;
441
  fPluginNameW: TFuncPluginNameW;
424
  fPluginVendorW: TFuncPluginVendorW;
442
  fPluginVendorW: TFuncPluginVendorW;
425
  fPluginVersionW: TFuncPluginVersionW;
443
  fPluginVersionW: TFuncPluginVersionW;
426
  fIdentificationMethodNameW: TFuncIdentificationMethodNameW;
444
  fIdentificationMethodNameW: TFuncIdentificationMethodNameW;
427
  fIdentificationStringW: TFuncIdentificationStringW;
445
  fIdentificationStringW: TFuncIdentificationStringW;
428
  fCheckLicense: TFuncCheckLicense;
446
  fCheckLicense: TFuncCheckLicense;
-
 
447
  fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW;
429
  statusCode: UD2_STATUS;
448
  statusCode: UD2_STATUS;
430
  i: integer;
449
  i: integer;
431
  starttime, endtime, time: cardinal;
450
  starttime, endtime, time: cardinal;
-
 
451
 
-
 
452
  function _ErrorLookup(statusCode: UD2_STATUS): WideString;
-
 
453
  var
-
 
454
    ret: BOOL;
-
 
455
  begin
-
 
456
    ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID);
-
 
457
    if ret then
-
 
458
    begin
432
  loadSuccessful: boolean;
459
      result := PWideChar(@buf);
-
 
460
      Exit;
-
 
461
    end;
-
 
462
    result := TUD2.GenericErrorLookup(statusCode);
-
 
463
  end;
-
 
464
 
433
resourcestring
465
resourcestring
434
  LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded.';
466
  LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded.';
435
  LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.';
467
  LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.';
436
  LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this program version.';
468
  LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this program version.';
437
  LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".';
469
  LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".';
438
begin
470
begin
439
  loadSuccessful := false;
471
  result := false;
440
  startTime := GetTickCount;
472
  startTime := GetTickCount;
441
 
473
 
442
  dllHandle := LoadLibrary(PChar(dllFile));
474
  dllHandle := LoadLibrary(PChar(dllFile));
443
  if dllHandle = 0 then
475
  if dllHandle = 0 then
444
  begin
476
  begin
Line 498... Line 530...
498
    begin
530
    begin
499
      Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationMethodNameW, dllFile]));
531
      Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationMethodNameW, dllFile]));
500
      Exit;
532
      Exit;
501
    end;
533
    end;
502
 
534
 
-
 
535
    @fDescribeOwnStatusCodeW := GetProcAddress(dllHandle, mnDescribeOwnStatusCodeW);
-
 
536
    if not Assigned(fDescribeOwnStatusCodeW) then
-
 
537
    begin
-
 
538
      Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDescribeOwnStatusCodeW, dllFile]));
-
 
539
      Exit;
-
 
540
    end;
-
 
541
 
503
    pl := TUD2Plugin.Create;
542
    pl := TUD2Plugin.Create;
504
    pl.PluginDLL := dllFile;
543
    pl.PluginDLL := dllFile;
505
 
544
 
506
    pluginIDfound := false;
545
    pluginIDfound := false;
507
    sPluginConfigFile := ChangeFileExt(dllFile, '.ini');
546
    sPluginConfigFile := ChangeFileExt(dllFile, '.ini');
Line 532... Line 571...
532
    end;
571
    end;
533
 
572
 
534
    statusCode := fCheckLicense(nil);
573
    statusCode := fCheckLicense(nil);
535
    if UD2_STATUS_Failed(statusCode) then
574
    if UD2_STATUS_Failed(statusCode) then
536
    begin
575
    begin
537
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnCheckLicense, dllFile]));
576
      Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnCheckLicense, dllFile]));
538
      Exit;
577
      Exit;
539
    end;
578
    end;
540
 
579
 
541
    statusCode := fPluginNameW(@buf, cchBufferSize, lngID);
580
    statusCode := fPluginNameW(@buf, cchBufferSize, lngID);
542
         if UD2_STATUS_Successful(statusCode) then pl.PluginName := PWideChar(@buf)
581
         if UD2_STATUS_Successful(statusCode) then pl.PluginName := PWideChar(@buf)
543
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginName := ''
582
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginName := ''
544
    else
583
    else
545
    begin
584
    begin
546
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnPluginNameW, dllFile]));
585
      Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile]));
547
      Exit;
586
      Exit;
548
    end;
587
    end;
549
 
588
 
550
    statusCode := fPluginVendorW(@buf, cchBufferSize, lngID);
589
    statusCode := fPluginVendorW(@buf, cchBufferSize, lngID);
551
         if UD2_STATUS_Successful(statusCode) then pl.PluginVendor := PWideChar(@buf)
590
         if UD2_STATUS_Successful(statusCode) then pl.PluginVendor := PWideChar(@buf)
552
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginVendor := ''
591
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginVendor := ''
553
    else
592
    else
554
    begin
593
    begin
555
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnPluginVendorW, dllFile]));
594
      Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile]));
556
      Exit;
595
      Exit;
557
    end;
596
    end;
558
 
597
 
559
    statusCode := fPluginVersionW(@buf, cchBufferSize, lngID);
598
    statusCode := fPluginVersionW(@buf, cchBufferSize, lngID);
560
         if UD2_STATUS_Successful(statusCode) then pl.PluginVersion := PWideChar(@buf)
599
         if UD2_STATUS_Successful(statusCode) then pl.PluginVersion := PWideChar(@buf)
561
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginVersion := ''
600
    else if UD2_STATUS_NotAvail(statusCode)   then pl.PluginVersion := ''
562
    else
601
    else
563
    begin
602
    begin
564
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnPluginVersionW, dllFile]));
603
      Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile]));
565
      Exit;
604
      Exit;
566
    end;
605
    end;
567
 
606
 
568
    statusCode := fIdentificationMethodNameW(@buf, cchBufferSize);
607
    statusCode := fIdentificationMethodNameW(@buf, cchBufferSize);
569
         if UD2_STATUS_Successful(statusCode) then pl.IdentificationMethodName := PWideChar(@buf)
608
         if UD2_STATUS_Successful(statusCode) then pl.IdentificationMethodName := PWideChar(@buf)
570
    else if UD2_STATUS_NotAvail(statusCode)   then pl.IdentificationMethodName := ''
609
    else if UD2_STATUS_NotAvail(statusCode)   then pl.IdentificationMethodName := ''
571
    else
610
    else
572
    begin
611
    begin
573
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile]));
612
      Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile]));
574
      Exit;
613
      Exit;
575
    end;
614
    end;
576
 
615
 
577
    statusCode := fIdentificationStringW(@buf, cchBufferSize);
616
    statusCode := fIdentificationStringW(@buf, cchBufferSize);
-
 
617
    pl.IdentificationProcedureStatusCode := statusCode;
-
 
618
    pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode);
578
    if UD2_STATUS_Successful(statusCode) then
619
    if UD2_STATUS_Successful(statusCode) then
579
    begin
620
    begin
580
      sIdentifier := PWideChar(@buf);
621
      sIdentifier := PWideChar(@buf);
581
      if statusCode = UD2_STATUS_OK_MULTILINE then
622
      if statusCode = UD2_STATUS_OK_MULTILINE then
582
      begin
623
      begin
583
        // Multiple identifiers (e.g. multiple MAC addresses are delimited via #10 )
624
        // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER)
584
        SetLength(sIdentifiers, 0);
625
        SetLength(sIdentifiers, 0);
585
        sIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier);
626
        sIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier);
586
        for i := Low(sIdentifiers) to High(sIdentifiers) do
627
        for i := Low(sIdentifiers) to High(sIdentifiers) do
587
        begin
628
        begin
588
          pl.AddIdentification(sIdentifiers[i]);
629
          pl.AddIdentification(sIdentifiers[i]);
Line 593... Line 634...
593
        pl.AddIdentification(sIdentifier);
634
        pl.AddIdentification(sIdentifier);
594
      end;
635
      end;
595
    end
636
    end
596
    else if not UD2_STATUS_NotAvail(statusCode) then
637
    else if not UD2_STATUS_NotAvail(statusCode) then
597
    begin
638
    begin
598
      Errors.Add(Format(LNG_METHOD_FAILURE, [UD2_ErrorLookup(statusCode), mnIdentificationStringW, dllFile]));
639
      // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile]));
-
 
640
      Errors.Add(Format(LNG_METHOD_FAILURE, [pl.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile]));
599
      Exit;
641
      Exit;
600
    end;
642
    end;
601
 
643
 
602
    endtime := GetTickCount;
644
    endtime := GetTickCount;
603
    time := endtime - starttime;
645
    time := endtime - starttime;
604
    if endtime < starttime then time := High(Cardinal) - time;
646
    if endtime < starttime then time := High(Cardinal) - time;
605
    pl.time := time;
647
    pl.time := time;
606
 
648
 
607
    loadSuccessful := true;
649
    result := true;
608
  finally
650
  finally
609
    if not loadSuccessful and Assigned(pl) then FreeAndNil(pl);
651
    if not result and Assigned(pl) then FreeAndNil(pl);
610
    FreeLibrary(dllHandle);
652
    FreeLibrary(dllHandle);
611
  end;
653
  end;
612
end;
654
end;
613
 
655
 
614
end.
656
end.