Rev 81 | Rev 83 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 81 | Rev 82 | ||
---|---|---|---|
Line 6... | Line 6... | ||
6 | {$LEGACYIFEND ON} |
6 | {$LEGACYIFEND ON} |
7 | {$IFEND} |
7 | {$IFEND} |
8 | 8 | ||
9 | {$INCLUDE 'UserDetect2.inc'} |
9 | {$INCLUDE 'UserDetect2.inc'} |
10 | 10 | ||
11 | {$WARN UNSAFE_CODE OFF} |
- | |
12 | {$WARN UNSAFE_TYPE OFF} |
- | |
13 | - | ||
14 | uses |
11 | uses |
15 | Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf, |
12 | Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf, |
16 | UD2_PluginStatus; |
13 | UD2_PluginStatus; |
17 | 14 | ||
18 | const |
15 | const |
Line 21... | Line 18... | ||
21 | type |
18 | type |
22 | TUD2Plugin = class(TObject) |
19 | TUD2Plugin = class(TObject) |
23 | protected |
20 | protected |
24 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
21 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
25 | public |
22 | public |
- | 23 | // This flag will be set if "AutoOSNotSupportedCompatibility" of the INI manifest had to be enforced/used |
|
- | 24 | OSNotSupportedEnforced: boolean; |
|
- | 25 | ||
26 | PluginDLL: string; |
26 | PluginDLL: string; |
27 | PluginGUID: TGUID; |
27 | PluginGUID: TGUID; |
28 | PluginName: WideString; |
28 | PluginName: WideString; |
29 | PluginVendor: WideString; |
29 | PluginVendor: WideString; |
30 | PluginVersion: WideString; |
30 | PluginVersion: WideString; |
Line 68... | Line 68... | ||
68 | public |
68 | public |
69 | property IniFileName: string read FIniFileName; |
69 | property IniFileName: string read FIniFileName; |
70 | property Errors: TStrings read FErrors; |
70 | property Errors: TStrings read FErrors; |
71 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
71 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
72 | property IniFile: TMemIniFile read FIniFile; |
72 | property IniFile: TMemIniFile read FIniFile; |
73 | - | ||
74 | procedure GetAllIdNames(outSL: TStrings); |
73 | procedure GetAllIdNames(outSL: TStrings); |
75 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
74 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
76 | - | ||
77 | - | ||
78 | procedure GetCommandList(ShortTaskName: string; outSL: TStrings); |
75 | procedure GetCommandList(ShortTaskName: string; outSL: TStrings); |
79 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
76 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
80 | procedure GetTaskListing(outSL: TStrings); |
77 | procedure GetTaskListing(outSL: TStrings); |
81 | constructor Create(AIniFileName: string); |
78 | constructor Create(AIniFileName: string); |
82 | destructor Destroy; override; |
79 | destructor Destroy; override; |
Line 118... | Line 115... | ||
118 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
115 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
119 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
116 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
120 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
117 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
121 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
118 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
122 | 119 | ||
123 | LNG_STATUS_ERROR_UNSPECIFIED = 'Error (Unspecified)'; |
120 | LNG_STATUS_FAILURE_UNSPECIFIED = 'Error (Unspecified)'; |
124 | LNG_STATUS_ERROR_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
121 | LNG_STATUS_FAILURE_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
125 | LNG_STATUS_ERROR_INVALID_ARGS = 'Error (The function received invalid arguments!)'; |
122 | LNG_STATUS_FAILURE_INVALID_ARGS = 'Error (The function received invalid arguments!)'; |
126 | LNG_STATUS_ERROR_PLUGIN_NOT_LICENSED = 'Error (The plugin is not licensed)'; |
123 | LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED = 'Error (The plugin is not licensed)'; |
- | 124 | LNG_STATUS_FAILURE_NO_RETURNED_VALUE = 'Error (Plugin did not return a status)'; |
|
- | 125 | LNG_STATUS_FAILURE_CATCHED_EXCEPTION = 'Error (Catched unexpected Exception)'; |
|
127 | LNG_UNKNOWN_FAILED = 'Error (Unknown status code %s)'; |
126 | LNG_UNKNOWN_FAILED = 'Error (Unknown status code %s)'; |
128 | 127 | ||
129 | LNG_UNKNOWN_STATUS = 'Unknown status code with unexpected category: %s'; |
128 | LNG_UNKNOWN_STATUS = 'Unknown status code with unexpected category: %s'; |
130 | begin |
129 | begin |
131 | if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_UNSPECIFIED, false) then result := LNG_STATUS_OK_UNSPECIFIED |
130 | if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_UNSPECIFIED, false) then result := LNG_STATUS_OK_UNSPECIFIED |
Line 136... | Line 135... | ||
136 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
135 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
137 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
136 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
138 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
137 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
139 | 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)]) |
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)]) |
140 | 139 | ||
141 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_ERROR_UNSPECIFIED |
140 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_FAILURE_UNSPECIFIED |
142 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_ERROR_BUFFER_TOO_SMALL |
141 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL |
143 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_ERROR_INVALID_ARGS |
142 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_FAILURE_INVALID_ARGS |
144 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_ERROR_PLUGIN_NOT_LICENSED |
143 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED |
- | 144 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_NO_RETURNED_VALUE, false) then result := LNG_STATUS_FAILURE_NO_RETURNED_VALUE |
|
- | 145 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_CATCHED_EXCEPTION, false) then result := LNG_STATUS_FAILURE_CATCHED_EXCEPTION |
|
145 | 146 | ||
146 | else if grStatus.wCategory = UD2_STATUSCAT_SUCCESS then result := Format(LNG_UNKNOWN_SUCCESS, [UD2_STATUS_FormatStatusCode(grStatus)]) |
147 | else if grStatus.wCategory = UD2_STATUSCAT_SUCCESS then result := Format(LNG_UNKNOWN_SUCCESS, [UD2_STATUS_FormatStatusCode(grStatus)]) |
147 | else if grStatus.wCategory = UD2_STATUSCAT_NOT_AVAIL then result := Format(LNG_UNKNOWN_NOTAVAIL, [UD2_STATUS_FormatStatusCode(grStatus)]) |
148 | else if grStatus.wCategory = UD2_STATUSCAT_NOT_AVAIL then result := Format(LNG_UNKNOWN_NOTAVAIL, [UD2_STATUS_FormatStatusCode(grStatus)]) |
148 | else if grStatus.wCategory = UD2_STATUSCAT_FAILED then result := Format(LNG_UNKNOWN_FAILED, [UD2_STATUS_FormatStatusCode(grStatus)]) |
149 | else if grStatus.wCategory = UD2_STATUSCAT_FAILED then result := Format(LNG_UNKNOWN_FAILED, [UD2_STATUS_FormatStatusCode(grStatus)]) |
149 | else result := Format(LNG_UNKNOWN_STATUS, [UD2_STATUS_FormatStatusCode(grStatus)]); |
150 | else result := Format(LNG_UNKNOWN_STATUS, [UD2_STATUS_FormatStatusCode(grStatus)]); |
Line 181... | Line 182... | ||
181 | end; |
182 | end; |
182 | 183 | ||
183 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
184 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
184 | begin |
185 | begin |
185 | sl.Add(GetPrimaryIdName); |
186 | sl.Add(GetPrimaryIdName); |
186 | sl.Add(UpperCase(Plugin.IdentificationMethodName)+':'+IdentificationString); |
- | |
187 | sl.Add(LowerCase(Plugin.IdentificationMethodName)+':'+IdentificationString); |
187 | sl.Add(Plugin.IdentificationMethodName+':'+IdentificationString); |
188 | sl.Add(UpperCase(Plugin.PluginGUIDString)+':'+IdentificationString); |
- | |
189 | sl.Add(LowerCase(Plugin.PluginGUIDString)+':'+IdentificationString); |
188 | sl.Add(Plugin.PluginGUIDString+':'+IdentificationString); |
190 | end; |
189 | end; |
191 | 190 | ||
192 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
191 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
193 | APlugin: TUD2Plugin); |
192 | APlugin: TUD2Plugin); |
194 | begin |
193 | begin |
Line 246... | Line 245... | ||
246 | pluginLoader.WaitFor; |
245 | pluginLoader.WaitFor; |
247 | Errors.AddStrings(pluginLoader.Errors); |
246 | Errors.AddStrings(pluginLoader.Errors); |
248 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
247 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
249 | if Assigned(pluginLoader.pl) then |
248 | if Assigned(pluginLoader.pl) then |
250 | begin |
249 | begin |
- | 250 | if not pluginLoader.pl.OSNotSupportedEnforced then |
|
- | 251 | begin |
|
251 | sPluginID := GUIDToString(pluginLoader.pl.PluginGUID); |
252 | sPluginID := GUIDToString(pluginLoader.pl.PluginGUID); |
252 | prevDLL := FGUIDLookup.Values[sPluginID]; |
253 | prevDLL := FGUIDLookup.Values[sPluginID]; |
253 | if (prevDLL <> '') and (prevDLL <> pluginLoader.pl.PluginDLL) then |
254 | if (prevDLL <> '') and (prevDLL <> pluginLoader.pl.PluginDLL) then |
254 | begin |
255 | begin |
255 | Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.pl.PluginDLL])); |
256 | Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.pl.PluginDLL])); |
Line 259... | Line 260... | ||
259 | begin |
260 | begin |
260 | FGUIDLookup.Values[sPluginID] := pluginLoader.pl.PluginDLL; |
261 | FGUIDLookup.Values[sPluginID] := pluginLoader.pl.PluginDLL; |
261 | LoadedPlugins.Add(pluginLoader.pl); |
262 | LoadedPlugins.Add(pluginLoader.pl); |
262 | end; |
263 | end; |
263 | end; |
264 | end; |
- | 265 | end; |
|
264 | {$ENDIF} |
266 | {$ENDIF} |
265 | pluginLoader.Free; |
267 | pluginLoader.Free; |
266 | end; |
268 | end; |
267 | finally |
269 | finally |
268 | tob.free; |
270 | tob.free; |
Line 363... | Line 365... | ||
363 | end; |
365 | end; |
364 | end; |
366 | end; |
365 | end; |
367 | end; |
366 | 368 | ||
367 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
369 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
- | 370 | const |
|
- | 371 | CASE_SENSITIVE_FLAG = '$CASESENSITIVE$'; |
|
368 | var |
372 | var |
369 | x: TArrayOfString; |
373 | x: TArrayOfString; |
370 | i: integer; |
374 | i: integer; |
371 | idName: WideString; |
375 | idName: WideString; |
372 | cleanUpStringList: boolean; |
376 | cleanUpStringList: boolean; |
- | 377 | caseSensitive: boolean; |
|
373 | begin |
378 | begin |
374 | cleanUpStringList := slIdNames = nil; |
379 | cleanUpStringList := slIdNames = nil; |
375 | try |
380 | try |
376 | if cleanUpStringList then |
381 | if cleanUpStringList then |
377 | begin |
382 | begin |
Line 389... | Line 394... | ||
389 | result := true; |
394 | result := true; |
390 | for i := Low(x) to High(x) do |
395 | for i := Low(x) to High(x) do |
391 | begin |
396 | begin |
392 | idName := x[i]; |
397 | idName := x[i]; |
393 | 398 | ||
- | 399 | if Pos(CASE_SENSITIVE_FLAG, idName) >= 1 then |
|
- | 400 | begin |
|
- | 401 | idName := StringReplace(idName, CASE_SENSITIVE_FLAG, '', [rfReplaceAll]); |
|
- | 402 | caseSensitive := true; |
|
- | 403 | end |
|
- | 404 | else |
|
- | 405 | begin |
|
- | 406 | caseSensitive := false; |
|
- | 407 | end; |
|
- | 408 | ||
394 | if slIdNames.IndexOf(idName) = -1 then |
409 | if (not caseSensitive and (slIdNames.IndexOf(idName) = -1)) or |
- | 410 | (caseSensitive and (IndexOf_CS(slIdNames, idName) = -1)) then |
|
395 | begin |
411 | begin |
396 | result := false; |
412 | result := false; |
397 | break; |
413 | break; |
398 | end; |
414 | end; |
399 | end; |
415 | end; |
Line 466... | Line 482... | ||
466 | function TUD2PluginLoader.HandleDLL: boolean; |
482 | function TUD2PluginLoader.HandleDLL: boolean; |
467 | var |
483 | var |
468 | sIdentifier: WideString; |
484 | sIdentifier: WideString; |
469 | sIdentifiers: TArrayOfString; |
485 | sIdentifiers: TArrayOfString; |
470 | buf: array[0..cchBufferSize-1] of WideChar; |
486 | buf: array[0..cchBufferSize-1] of WideChar; |
471 | sPluginConfigFile: string; |
- | |
472 | iniConfig: TINIFile; |
- | |
473 | sOverrideGUID: string; |
- | |
474 | pluginIDfound: boolean; |
- | |
475 | pluginInterfaceID: TGUID; |
487 | pluginInterfaceID: TGUID; |
476 | dllHandle: Cardinal; |
488 | dllHandle: Cardinal; |
477 | fPluginInterfaceID: TFuncPluginInterfaceID; |
489 | fPluginInterfaceID: TFuncPluginInterfaceID; |
478 | fPluginIdentifier: TFuncPluginIdentifier; |
490 | fPluginIdentifier: TFuncPluginIdentifier; |
479 | fPluginNameW: TFuncPluginNameW; |
491 | fPluginNameW: TFuncPluginNameW; |
Line 484... | Line 496... | ||
484 | fCheckLicense: TFuncCheckLicense; |
496 | fCheckLicense: TFuncCheckLicense; |
485 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
497 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
486 | statusCode: UD2_STATUS; |
498 | statusCode: UD2_STATUS; |
487 | i: integer; |
499 | i: integer; |
488 | starttime, endtime, time: cardinal; |
500 | starttime, endtime, time: cardinal; |
- | 501 | bakErrorMode: DWORD; |
|
- | 502 | err: DWORD; |
|
489 | 503 | ||
490 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
504 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
491 | var |
505 | var |
492 | ret: BOOL; |
506 | ret: BOOL; |
493 | begin |
507 | begin |
- | 508 | if Assigned(fDescribeOwnStatusCodeW) then |
|
- | 509 | begin |
|
- | 510 | ZeroMemory(@buf, cchBufferSize); |
|
494 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
511 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
495 | if ret then |
512 | if ret then |
496 | begin |
513 | begin |
497 | result := PWideChar(@buf); |
514 | result := PWideChar(@buf); |
498 | Exit; |
515 | Exit; |
499 | end; |
516 | end; |
- | 517 | end; |
|
500 | result := TUD2.GenericErrorLookup(statusCode); |
518 | result := TUD2.GenericErrorLookup(statusCode); |
501 | end; |
519 | end; |
502 | 520 | ||
- | 521 | function _ApplyCompatibilityGUID: boolean; |
|
- | 522 | var |
|
- | 523 | iniConfig: TIniFile; |
|
- | 524 | sOverrideGUID: string; |
|
- | 525 | sPluginConfigFile: string; |
|
- | 526 | begin |
|
- | 527 | result := false; |
|
- | 528 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
|
- | 529 | if FileExists(sPluginConfigFile) then |
|
- | 530 | begin |
|
- | 531 | iniConfig := TIniFile.Create(sPluginConfigFile); |
|
- | 532 | try |
|
- | 533 | sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', ''); |
|
- | 534 | if sOverrideGUID <> '' then |
|
- | 535 | begin |
|
- | 536 | pl.PluginGUID := StringToGUID(sOverrideGUID); |
|
- | 537 | result := true; |
|
- | 538 | end; |
|
- | 539 | finally |
|
- | 540 | iniConfig.Free; |
|
- | 541 | end; |
|
- | 542 | end; |
|
- | 543 | end; |
|
- | 544 | ||
- | 545 | function _AutoOSNotSupportedMode: integer; |
|
- | 546 | var |
|
- | 547 | iniConfig: TIniFile; |
|
- | 548 | sPluginConfigFile: string; |
|
- | 549 | begin |
|
- | 550 | result := 0; |
|
- | 551 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
|
- | 552 | if FileExists(sPluginConfigFile) then |
|
- | 553 | begin |
|
- | 554 | iniConfig := TIniFile.Create(sPluginConfigFile); |
|
- | 555 | try |
|
- | 556 | result := iniConfig.ReadInteger('Compatibility', 'AutoOSNotSupported', 0); |
|
- | 557 | finally |
|
- | 558 | iniConfig.Free; |
|
- | 559 | end; |
|
- | 560 | end; |
|
- | 561 | end; |
|
- | 562 | ||
- | 563 | procedure _OverwriteStatusToOSNotSupported; |
|
- | 564 | begin |
|
- | 565 | pl := TUD2Plugin.Create; |
|
- | 566 | pl.PluginDLL := dllFile; |
|
- | 567 | statusCode := UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED; |
|
- | 568 | pl.IdentificationProcedureStatusCode := statusCode; |
|
- | 569 | pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
|
- | 570 | (* |
|
- | 571 | if not _ApplyCompatibilityGUID then |
|
- | 572 | begin |
|
- | 573 | CreateGUID(pl.PluginGUID); // to avoid the "double GUID" error |
|
- | 574 | end; |
|
- | 575 | *) |
|
- | 576 | pl.OSNotSupportedEnforced := true; // to avoid the "double GUID" error |
|
- | 577 | result := true; |
|
- | 578 | end; |
|
- | 579 | ||
503 | resourcestring |
580 | resourcestring |
504 | LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded.'; |
581 | LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded: %s'; |
505 | LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.'; |
582 | LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.'; |
506 | LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this application.'; |
583 | LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this application.'; |
507 | LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".'; |
584 | LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".'; |
- | 585 | LNG_EXCEPTION = 'Fatal error while loading "%s" (%s: %s)'; |
|
508 | begin |
586 | begin |
509 | result := false; |
587 | result := false; |
510 | startTime := GetTickCount; |
588 | startTime := GetTickCount; |
511 | 589 | ||
- | 590 | try |
|
- | 591 | bakErrorMode := 0; |
|
- | 592 | UD2_SetThreadErrorMode(SEM_FAILCRITICALERRORS, Pointer(bakErrorMode)); |
|
- | 593 | try |
|
512 | dllHandle := LoadLibrary(PChar(dllFile)); |
594 | dllHandle := LoadLibrary(PChar(dllFile)); |
513 | if dllHandle = 0 then |
595 | if dllHandle = 0 then |
514 | begin |
596 | begin |
- | 597 | err := GetLastError; |
|
- | 598 | ||
- | 599 | if ((_AutoOSNotSupportedMode = 1) and ((err = ERROR_DLL_NOT_FOUND) or (err = ERROR_PROC_NOT_FOUND))) or |
|
- | 600 | (_AutoOSNotSupportedMode >= 2) then |
|
- | 601 | begin |
|
- | 602 | _OverwriteStatusToOSNotSupported; |
|
- | 603 | Exit; |
|
- | 604 | end; |
|
- | 605 | ||
515 | Errors.Add(Format(LNG_DLL_NOT_LOADED, [dllFile])); |
606 | Errors.Add(Format(LNG_DLL_NOT_LOADED, [dllFile, SysErrorMessage(err)])); |
- | 607 | Exit; |
|
516 | end; |
608 | end; |
517 | try |
609 | try |
518 | @fPluginInterfaceID := GetProcAddress(dllHandle, mnPluginInterfaceID); |
610 | @fPluginInterfaceID := GetProcAddress(dllHandle, mnPluginInterfaceID); |
519 | if not Assigned(fPluginInterfaceID) then |
611 | if not Assigned(fPluginInterfaceID) then |
520 | begin |
612 | begin |
Line 578... | Line 670... | ||
578 | end; |
670 | end; |
579 | 671 | ||
580 | pl := TUD2Plugin.Create; |
672 | pl := TUD2Plugin.Create; |
581 | pl.PluginDLL := dllFile; |
673 | pl.PluginDLL := dllFile; |
582 | 674 | ||
583 | pluginIDfound := false; |
- | |
584 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
- | |
585 | if FileExists(sPluginConfigFile) then |
- | |
586 | begin |
- | |
587 | iniConfig := TIniFile.Create(sPluginConfigFile); |
- | |
588 | try |
- | |
589 | sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', ''); |
- | |
590 | if sOverrideGUID <> '' then |
- | |
591 | begin |
- | |
592 | pl.PluginGUID := StringToGUID(sOverrideGUID); |
- | |
593 | pluginIDfound := true; |
- | |
594 | end; |
- | |
595 | finally |
- | |
596 | iniConfig.Free; |
- | |
597 | end; |
- | |
598 | end; |
- | |
599 | - | ||
600 | if not pluginIDfound then |
675 | if not _ApplyCompatibilityGUID then |
601 | begin |
676 | begin |
602 | @fPluginIdentifier := GetProcAddress(dllHandle, mnPluginIdentifier); |
677 | @fPluginIdentifier := GetProcAddress(dllHandle, mnPluginIdentifier); |
603 | if not Assigned(fPluginIdentifier) then |
678 | if not Assigned(fPluginIdentifier) then |
604 | begin |
679 | begin |
605 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile])); |
680 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile])); |
Line 613... | Line 688... | ||
613 | begin |
688 | begin |
614 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnCheckLicense, dllFile])); |
689 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnCheckLicense, dllFile])); |
615 | Exit; |
690 | Exit; |
616 | end; |
691 | end; |
617 | 692 | ||
- | 693 | ZeroMemory(@buf, cchBufferSize); |
|
618 | statusCode := fPluginNameW(@buf, cchBufferSize, lngID); |
694 | statusCode := fPluginNameW(@buf, cchBufferSize, lngID); |
619 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginName := PWideChar(@buf) |
695 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginName := PWideChar(@buf) |
620 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginName := '' |
696 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginName := '' |
621 | else |
697 | else |
622 | begin |
698 | begin |
623 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile])); |
699 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile])); |
624 | Exit; |
700 | Exit; |
625 | end; |
701 | end; |
626 | 702 | ||
- | 703 | ZeroMemory(@buf, cchBufferSize); |
|
627 | statusCode := fPluginVendorW(@buf, cchBufferSize, lngID); |
704 | statusCode := fPluginVendorW(@buf, cchBufferSize, lngID); |
628 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginVendor := PWideChar(@buf) |
705 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginVendor := PWideChar(@buf) |
629 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginVendor := '' |
706 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginVendor := '' |
630 | else |
707 | else |
631 | begin |
708 | begin |
632 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile])); |
709 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile])); |
633 | Exit; |
710 | Exit; |
634 | end; |
711 | end; |
635 | 712 | ||
- | 713 | ZeroMemory(@buf, cchBufferSize); |
|
636 | statusCode := fPluginVersionW(@buf, cchBufferSize, lngID); |
714 | statusCode := fPluginVersionW(@buf, cchBufferSize, lngID); |
637 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginVersion := PWideChar(@buf) |
715 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.PluginVersion := PWideChar(@buf) |
638 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginVersion := '' |
716 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.PluginVersion := '' |
639 | else |
717 | else |
640 | begin |
718 | begin |
641 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile])); |
719 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile])); |
642 | Exit; |
720 | Exit; |
643 | end; |
721 | end; |
644 | 722 | ||
- | 723 | ZeroMemory(@buf, cchBufferSize); |
|
645 | statusCode := fIdentificationMethodNameW(@buf, cchBufferSize); |
724 | statusCode := fIdentificationMethodNameW(@buf, cchBufferSize); |
646 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.IdentificationMethodName := PWideChar(@buf) |
725 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then pl.IdentificationMethodName := PWideChar(@buf) |
647 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.IdentificationMethodName := '' |
726 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then pl.IdentificationMethodName := '' |
648 | else |
727 | else |
649 | begin |
728 | begin |
650 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile])); |
729 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile])); |
651 | Exit; |
730 | Exit; |
652 | end; |
731 | end; |
653 | 732 | ||
- | 733 | 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) |
|
654 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
735 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
655 | pl.IdentificationProcedureStatusCode := statusCode; |
736 | pl.IdentificationProcedureStatusCode := statusCode; |
656 | pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
737 | pl.IdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
657 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
738 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
658 | begin |
739 | begin |
Line 672... | Line 753... | ||
672 | pl.AddIdentification(sIdentifier); |
753 | pl.AddIdentification(sIdentifier); |
673 | end; |
754 | end; |
674 | end |
755 | end |
675 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
756 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
676 | begin |
757 | begin |
- | 758 | if _AutoOSNotSupportedMode >= 3 then |
|
- | 759 | begin |
|
- | 760 | _OverwriteStatusToOSNotSupported; |
|
- | 761 | Exit; |
|
- | 762 | end; |
|
- | 763 | ||
677 | // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile])); |
764 | // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile])); |
678 | Errors.Add(Format(LNG_METHOD_FAILURE, [pl.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile])); |
765 | Errors.Add(Format(LNG_METHOD_FAILURE, [pl.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile])); |
679 | Exit; |
766 | Exit; |
680 | end; |
767 | end; |
681 | 768 | ||
682 | endtime := GetTickCount; |
- | |
683 | time := endtime - starttime; |
- | |
684 | if endtime < starttime then time := High(Cardinal) - time; |
- | |
685 | pl.time := time; |
- | |
686 | - | ||
687 | result := true; |
769 | result := true; |
688 | finally |
770 | finally |
689 | if not result and Assigned(pl) then FreeAndNil(pl); |
771 | if not result and Assigned(pl) then FreeAndNil(pl); |
690 | FreeLibrary(dllHandle); |
772 | FreeLibrary(dllHandle); |
691 | end; |
773 | end; |
- | 774 | finally |
|
- | 775 | UD2_SetThreadErrorMode(bakErrorMode, nil); |
|
- | 776 | ||
- | 777 | if result then |
|
- | 778 | begin |
|
- | 779 | endtime := GetTickCount; |
|
- | 780 | time := endtime - starttime; |
|
- | 781 | if endtime < starttime then time := High(Cardinal) - time; |
|
- | 782 | pl.time := time; |
|
- | 783 | end; |
|
- | 784 | end; |
|
- | 785 | except |
|
- | 786 | // TODO: when an exception happens in a cdecl DLL, then this code is somehow not |
|
- | 787 | // executed. Probably the memory is corrupted. Anyway, a cdecl DLL shall NEVER |
|
- | 788 | // raise an Exception. |
|
- | 789 | on E: Exception do |
|
- | 790 | begin |
|
- | 791 | Errors.Add(Format(LNG_EXCEPTION, [dllFile, E.ClassName, E.Message])); |
|
- | 792 | Exit; |
|
- | 793 | end; |
|
- | 794 | end; |
|
692 | end; |
795 | end; |
693 | 796 | ||
694 | end. |
797 | end. |