Rev 92 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 92 | Rev 94 | ||
---|---|---|---|
1 | unit UD2_Obj; |
1 | unit UD2_Obj; |
2 | 2 | ||
3 | interface |
3 | interface |
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'} |
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, UD2_Utils, UD2_Parsing; |
13 | UD2_PluginStatus, UD2_Utils, UD2_Parsing; |
14 | 14 | ||
15 | const |
15 | const |
16 | UD2_TagDescription = 'Description'; |
16 | UD2_TagDescription = 'Description'; |
17 | 17 | ||
18 | type |
18 | type |
19 | TUD2IdentificationEntry = class; |
19 | TUD2IdentificationEntry = class; |
20 | 20 | ||
21 | TUD2Plugin = class(TObject) |
21 | TUD2Plugin = class(TObject) |
22 | protected |
22 | protected |
23 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
23 | FDetectedIdentifications: TObjectList{<TUD2IdentificationEntry>}; |
24 | FOSNotSupportedEnforced: boolean; |
24 | FOSNotSupportedEnforced: boolean; |
25 | FPluginDLL: string; |
25 | FPluginDLL: string; |
26 | FPluginGUIDSet: boolean; |
26 | FPluginGUIDSet: boolean; |
27 | FPluginGUID: TGUID; |
27 | FPluginGUID: TGUID; |
28 | FPluginName: WideString; |
28 | FPluginName: WideString; |
29 | FPluginVendor: WideString; |
29 | FPluginVendor: WideString; |
30 | FPluginVersion: WideString; |
30 | FPluginVersion: WideString; |
31 | FIdentificationMethodName: WideString; |
31 | FIdentificationMethodName: WideString; |
32 | FAcceptsDynamicRequests: boolean; |
32 | FAcceptsDynamicRequests: boolean; |
33 | FIdentificationProcedureStatusCode: UD2_STATUS; |
33 | FIdentificationProcedureStatusCode: UD2_STATUS; |
34 | FIdentificationProcedureStatusCodeDescribed: WideString; |
34 | FIdentificationProcedureStatusCodeDescribed: WideString; |
35 | FLoadingTime: Cardinal; |
35 | FLoadingTime: Cardinal; |
36 | public |
36 | public |
37 | // This flag will be set if "AutoOSNotSupportedCompatibility" of the INI manifest had to be enforced/used |
37 | // This flag will be set if "AutoOSNotSupportedCompatibility" of the INI manifest had to be enforced/used |
38 | property OSNotSupportedEnforced: boolean read FOSNotSupportedEnforced; |
38 | property OSNotSupportedEnforced: boolean read FOSNotSupportedEnforced; |
39 | 39 | ||
40 | // Data read from the DLL |
40 | // Data read from the DLL |
41 | property PluginDLL: string read FPluginDLL; |
41 | property PluginDLL: string read FPluginDLL; |
42 | property PluginGUIDSet: boolean read FPluginGUIDSet; |
42 | property PluginGUIDSet: boolean read FPluginGUIDSet; |
43 | property PluginGUID: TGUID read FPluginGUID; |
43 | property PluginGUID: TGUID read FPluginGUID; |
44 | property PluginName: WideString read FPluginName; |
44 | property PluginName: WideString read FPluginName; |
45 | property PluginVendor: WideString read FPluginVendor; |
45 | property PluginVendor: WideString read FPluginVendor; |
46 | property PluginVersion: WideString read FPluginVersion; |
46 | property PluginVersion: WideString read FPluginVersion; |
47 | property IdentificationMethodName: WideString read FIdentificationMethodName; |
47 | property IdentificationMethodName: WideString read FIdentificationMethodName; |
48 | property AcceptsDynamicRequests: boolean read FAcceptsDynamicRequests; |
48 | property AcceptsDynamicRequests: boolean read FAcceptsDynamicRequests; |
49 | 49 | ||
50 | // ONLY contains the non-failure status code of IdentificationStringW |
50 | // ONLY contains the non-failure status code of IdentificationStringW |
51 | property IdentificationProcedureStatusCode: UD2_STATUS read FIdentificationProcedureStatusCode; |
51 | property IdentificationProcedureStatusCode: UD2_STATUS read FIdentificationProcedureStatusCode; |
52 | property IdentificationProcedureStatusCodeDescribed: WideString read FIdentificationProcedureStatusCodeDescribed; |
52 | property IdentificationProcedureStatusCodeDescribed: WideString read FIdentificationProcedureStatusCodeDescribed; |
53 | 53 | ||
54 | // How long did the plugin to load? |
54 | // How long did the plugin to load? |
55 | property LoadingTime: Cardinal read FLoadingTime; |
55 | property LoadingTime: Cardinal read FLoadingTime; |
56 | 56 | ||
57 | function PluginGUIDString: string; |
57 | function PluginGUIDString: string; |
58 | property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} read FDetectedIdentifications; |
58 | property DetectedIdentifications: TObjectList{<TUD2IdentificationEntry>} read FDetectedIdentifications; |
59 | destructor Destroy; override; |
59 | destructor Destroy; override; |
60 | constructor Create; |
60 | constructor Create; |
61 | function AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
61 | function AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
62 | 62 | ||
63 | function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean; overload; |
63 | function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean; overload; |
64 | function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean; overload; |
64 | function InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean; overload; |
65 | function GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString; |
65 | function GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString; |
66 | 66 | ||
67 | function EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
67 | function EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
68 | end; |
68 | end; |
69 | 69 | ||
70 | TUD2IdentificationEntry = class(TObject) |
70 | TUD2IdentificationEntry = class(TObject) |
71 | private |
71 | private |
72 | FIdentificationString: WideString; |
72 | FIdentificationString: WideString; |
73 | FPlugin: TUD2Plugin; |
73 | FPlugin: TUD2Plugin; |
74 | FDynamicDataUsed: boolean; |
74 | FDynamicDataUsed: boolean; |
75 | FDynamicData: WideString; |
75 | FDynamicData: WideString; |
76 | public |
76 | public |
77 | property DynamicDataUsed: boolean read FDynamicDataUsed write FDynamicDataUsed; |
77 | property DynamicDataUsed: boolean read FDynamicDataUsed write FDynamicDataUsed; |
78 | property DynamicData: WideString read FDynamicData write FDynamicData; |
78 | property DynamicData: WideString read FDynamicData write FDynamicData; |
79 | property IdentificationString: WideString read FIdentificationString; |
79 | property IdentificationString: WideString read FIdentificationString; |
80 | property Plugin: TUD2Plugin read FPlugin; |
80 | property Plugin: TUD2Plugin read FPlugin; |
- | 81 | function GetConditionString(MethodnameAsGUID: boolean=false): TUD2TDFCondition; |
|
81 | procedure GetIdNames(sl: TStrings); |
82 | procedure GetIdNames(sl: TStrings); |
82 | constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin); |
83 | constructor Create(AIdentificationString: WideString; APlugin: TUD2Plugin); |
83 | end; |
84 | end; |
84 | 85 | ||
85 | TUD2 = class(TObject) |
86 | TUD2 = class(TObject) |
86 | private |
87 | private |
87 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
88 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
88 | FGUIDLookup: TStrings; |
89 | FGUIDLookup: TStrings; |
89 | {$ENDIF} |
90 | {$ENDIF} |
90 | protected |
91 | protected |
91 | FLoadedPlugins: TObjectList{<TUD2Plugin>}; |
92 | FLoadedPlugins: TObjectList{<TUD2Plugin>}; |
92 | FIniFile: TMemIniFile; |
93 | FIniFile: TMemIniFile; |
93 | FErrors: TStrings; |
94 | FErrors: TStrings; |
94 | FIniFileName: string; |
95 | FIniFileName: string; |
95 | public |
96 | public |
96 | property IniFileName: string read FIniFileName; |
97 | property IniFileName: string read FIniFileName; |
97 | property Errors: TStrings read FErrors; |
98 | property Errors: TStrings read FErrors; |
98 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
99 | property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
99 | property IniFile: TMemIniFile read FIniFile; |
100 | property IniFile: TMemIniFile read FIniFile; |
100 | procedure GetAllDetectedIDs(outSL: TStrings); |
101 | procedure GetAllDetectedIDs(outSL: TStrings); |
101 | function FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload; |
102 | function FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload; |
102 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload; |
103 | function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; overload; |
103 | function CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray; |
104 | function CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray; |
104 | function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
105 | function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
105 | function GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray; |
106 | function GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray; |
106 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
107 | procedure HandlePluginDir(APluginDir, AFileMask: string); |
107 | procedure GetTaskListing(outSL: TStrings); |
108 | procedure GetTaskListing(outSL: TStrings); |
108 | constructor Create(AIniFileName: string); |
109 | constructor Create(AIniFileName: string); |
109 | destructor Destroy; override; |
110 | destructor Destroy; override; |
110 | function TaskExists(ShortTaskName: string): boolean; |
111 | function TaskExists(ShortTaskName: string): boolean; |
111 | function ReadMetatagString(ShortTaskName, MetatagName: string; DefaultVal: string): string; |
112 | function ReadMetatagString(ShortTaskName, MetatagName: string; DefaultVal: string): string; |
112 | function ReadMetatagBool(ShortTaskName, MetatagName: string; DefaultVal: string): boolean; |
113 | function ReadMetatagBool(ShortTaskName, MetatagName: string; DefaultVal: string): boolean; |
113 | function GetTaskName(AShortTaskName: string): string; |
114 | function GetTaskName(AShortTaskName: string): string; |
114 | class function GenericErrorLookup(grStatus: UD2_STATUS): string; |
115 | class function GenericErrorLookup(grStatus: UD2_STATUS): string; |
115 | end; |
116 | end; |
116 | 117 | ||
117 | implementation |
118 | implementation |
118 | 119 | ||
119 | uses |
120 | uses |
120 | Math; |
121 | Math; |
121 | 122 | ||
122 | const |
123 | const |
123 | cchBufferSize = 32768; |
124 | cchBufferSize = 32768; |
124 | 125 | ||
125 | type |
126 | type |
126 | TUD2PluginLoader = class(TThread) |
127 | TUD2PluginLoader = class(TThread) |
127 | protected |
128 | protected |
128 | dllFile: string; |
129 | dllFile: string; |
129 | lngID: LANGID; |
130 | lngID: LANGID; |
130 | useDynamicData: boolean; |
131 | useDynamicData: boolean; |
131 | dynamicData: WideString; |
132 | dynamicData: WideString; |
132 | procedure Execute; override; |
133 | procedure Execute; override; |
133 | function HandleDLL: boolean; |
134 | function HandleDLL: boolean; |
134 | public |
135 | public |
135 | Plugin: TUD2Plugin; |
136 | Plugin: TUD2Plugin; |
136 | Errors: TStringList; |
137 | Errors: TStringList; |
137 | ResultIdentifiers: TArrayOfString; |
138 | ResultIdentifiers: TArrayOfString; |
138 | constructor Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
139 | constructor Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
139 | destructor Destroy; override; |
140 | destructor Destroy; override; |
140 | end; |
141 | end; |
141 | 142 | ||
142 | class function TUD2.GenericErrorLookup(grStatus: UD2_STATUS): string; |
143 | class function TUD2.GenericErrorLookup(grStatus: UD2_STATUS): string; |
143 | resourcestring |
144 | resourcestring |
144 | LNG_STATUS_OK_UNSPECIFIED = 'Success (Unspecified)'; |
145 | LNG_STATUS_OK_UNSPECIFIED = 'Success (Unspecified)'; |
145 | LNG_STATUS_OK_SINGLELINE = 'Success (One identifier returned)'; |
146 | LNG_STATUS_OK_SINGLELINE = 'Success (One identifier returned)'; |
146 | LNG_STATUS_OK_MULTILINE = 'Success (Multiple identifiers returned)'; |
147 | LNG_STATUS_OK_MULTILINE = 'Success (Multiple identifiers returned)'; |
147 | LNG_UNKNOWN_SUCCESS = 'Success (Unknown status code %s)'; |
148 | LNG_UNKNOWN_SUCCESS = 'Success (Unknown status code %s)'; |
148 | 149 | ||
149 | LNG_STATUS_NOTAVAIL_UNSPECIFIED = 'Not available (Unspecified)'; |
150 | LNG_STATUS_NOTAVAIL_UNSPECIFIED = 'Not available (Unspecified)'; |
150 | LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED = 'Not available (Operating system not supported)'; |
151 | LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED = 'Not available (Operating system not supported)'; |
151 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
152 | LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED = 'Not available (Hardware not supported)'; |
152 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
153 | LNG_STATUS_NOTAVAIL_NO_ENTITIES = 'Not available (No entities to identify)'; |
153 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
154 | LNG_STATUS_NOTAVAIL_WINAPI_CALL_FAILURE = 'Not available (A Windows API call failed. Message: %s)'; |
154 | LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC = 'Not available (Arguments required)'; |
155 | LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC = 'Not available (Arguments required)'; |
155 | LNG_STATUS_NOTAVAIL_INVALID_INPUT = 'Not available (Plugin received invalid input)'; |
156 | LNG_STATUS_NOTAVAIL_INVALID_INPUT = 'Not available (Plugin received invalid input)'; |
156 | LNG_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS = 'Not available (Plugin does not allow dynamic requests)'; |
157 | LNG_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS = 'Not available (Plugin does not allow dynamic requests)'; |
157 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
158 | LNG_UNKNOWN_NOTAVAIL = 'Not available (Unknown status code %s)'; |
158 | 159 | ||
159 | LNG_STATUS_FAILURE_UNSPECIFIED = 'Error (Unspecified)'; |
160 | LNG_STATUS_FAILURE_UNSPECIFIED = 'Error (Unspecified)'; |
160 | LNG_STATUS_FAILURE_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
161 | LNG_STATUS_FAILURE_BUFFER_TOO_SMALL = 'Error (The provided buffer is too small!)'; |
161 | LNG_STATUS_FAILURE_INVALID_ARGS = 'Error (An internal function received invalid arguments!)'; |
162 | LNG_STATUS_FAILURE_INVALID_ARGS = 'Error (An internal function received invalid arguments!)'; |
162 | LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED = 'Error (The plugin is not licensed)'; |
163 | LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED = 'Error (The plugin is not licensed)'; |
163 | LNG_STATUS_FAILURE_NO_RETURNED_VALUE = 'Error (Plugin did not return a status)'; |
164 | LNG_STATUS_FAILURE_NO_RETURNED_VALUE = 'Error (Plugin did not return a status)'; |
164 | LNG_STATUS_FAILURE_CATCHED_EXCEPTION = 'Error (Catched unexpected Exception)'; |
165 | LNG_STATUS_FAILURE_CATCHED_EXCEPTION = 'Error (Catched unexpected Exception)'; |
165 | LNG_UNKNOWN_FAILED = 'Error (Unknown status code %s)'; |
166 | LNG_UNKNOWN_FAILED = 'Error (Unknown status code %s)'; |
166 | 167 | ||
167 | LNG_UNKNOWN_STATUS = 'Unknown status code with unexpected category: %s'; |
168 | LNG_UNKNOWN_STATUS = 'Unknown status code with unexpected category: %s'; |
168 | begin |
169 | begin |
169 | if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_UNSPECIFIED, false) then result := LNG_STATUS_OK_UNSPECIFIED |
170 | if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_UNSPECIFIED, false) then result := LNG_STATUS_OK_UNSPECIFIED |
170 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_SINGLELINE, false) then result := LNG_STATUS_OK_SINGLELINE |
171 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_SINGLELINE, false) then result := LNG_STATUS_OK_SINGLELINE |
171 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_MULTILINE, false) then result := LNG_STATUS_OK_MULTILINE |
172 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_OK_MULTILINE, false) then result := LNG_STATUS_OK_MULTILINE |
172 | 173 | ||
173 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_UNSPECIFIED, false) then result := LNG_STATUS_NOTAVAIL_UNSPECIFIED |
174 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_UNSPECIFIED, false) then result := LNG_STATUS_NOTAVAIL_UNSPECIFIED |
174 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
175 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_OS_NOT_SUPPORTED |
175 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
176 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_HW_NOT_SUPPORTED, false) then result := LNG_STATUS_NOTAVAIL_HW_NOT_SUPPORTED |
176 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
177 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_NO_ENTITIES, false) then result := LNG_STATUS_NOTAVAIL_NO_ENTITIES |
177 | 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)]) |
178 | 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)]) |
178 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC, false) then result := LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC |
179 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC, false) then result := LNG_STATUS_NOTAVAIL_ONLY_ACCEPT_DYNAMIC |
179 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_INVALID_INPUT, false) then result := LNG_STATUS_NOTAVAIL_INVALID_INPUT |
180 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_INVALID_INPUT, false) then result := LNG_STATUS_NOTAVAIL_INVALID_INPUT |
180 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS, false) then result := LNG_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS |
181 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS, false) then result := LNG_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS |
181 | 182 | ||
182 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_FAILURE_UNSPECIFIED |
183 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_UNSPECIFIED, false) then result := LNG_STATUS_FAILURE_UNSPECIFIED |
183 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL |
184 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_BUFFER_TOO_SMALL, false) then result := LNG_STATUS_FAILURE_BUFFER_TOO_SMALL |
184 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_FAILURE_INVALID_ARGS |
185 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_INVALID_ARGS, false) then result := LNG_STATUS_FAILURE_INVALID_ARGS |
185 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED |
186 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_PLUGIN_NOT_LICENSED, false) then result := LNG_STATUS_FAILURE_PLUGIN_NOT_LICENSED |
186 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_NO_RETURNED_VALUE, false) then result := LNG_STATUS_FAILURE_NO_RETURNED_VALUE |
187 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_NO_RETURNED_VALUE, false) then result := LNG_STATUS_FAILURE_NO_RETURNED_VALUE |
187 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_CATCHED_EXCEPTION, false) then result := LNG_STATUS_FAILURE_CATCHED_EXCEPTION |
188 | else if UD2_STATUS_Equal(grStatus, UD2_STATUS_FAILURE_CATCHED_EXCEPTION, false) then result := LNG_STATUS_FAILURE_CATCHED_EXCEPTION |
188 | 189 | ||
189 | else if grStatus.wCategory = UD2_STATUSCAT_SUCCESS then result := Format(LNG_UNKNOWN_SUCCESS, [UD2_STATUS_FormatStatusCode(grStatus)]) |
190 | else if grStatus.wCategory = UD2_STATUSCAT_SUCCESS then result := Format(LNG_UNKNOWN_SUCCESS, [UD2_STATUS_FormatStatusCode(grStatus)]) |
190 | else if grStatus.wCategory = UD2_STATUSCAT_NOT_AVAIL then result := Format(LNG_UNKNOWN_NOTAVAIL, [UD2_STATUS_FormatStatusCode(grStatus)]) |
191 | else if grStatus.wCategory = UD2_STATUSCAT_NOT_AVAIL then result := Format(LNG_UNKNOWN_NOTAVAIL, [UD2_STATUS_FormatStatusCode(grStatus)]) |
191 | else if grStatus.wCategory = UD2_STATUSCAT_FAILED then result := Format(LNG_UNKNOWN_FAILED, [UD2_STATUS_FormatStatusCode(grStatus)]) |
192 | else if grStatus.wCategory = UD2_STATUSCAT_FAILED then result := Format(LNG_UNKNOWN_FAILED, [UD2_STATUS_FormatStatusCode(grStatus)]) |
192 | else result := Format(LNG_UNKNOWN_STATUS, [UD2_STATUS_FormatStatusCode(grStatus)]); |
193 | else result := Format(LNG_UNKNOWN_STATUS, [UD2_STATUS_FormatStatusCode(grStatus)]); |
193 | end; |
194 | end; |
194 | 195 | ||
195 | { TUD2Plugin } |
196 | { TUD2Plugin } |
196 | 197 | ||
197 | function TUD2Plugin.PluginGUIDString: string; |
198 | function TUD2Plugin.PluginGUIDString: string; |
198 | begin |
199 | begin |
199 | if PluginGUIDSet then |
200 | if PluginGUIDSet then |
200 | result := UpperCase(GUIDToString(PluginGUID)) |
201 | result := UpperCase(GUIDToString(PluginGUID)) |
201 | else |
202 | else |
202 | result := ''; |
203 | result := ''; |
203 | end; |
204 | end; |
204 | 205 | ||
205 | function TUD2Plugin.AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
206 | function TUD2Plugin.AddIdentification(IdStr: WideString): TUD2IdentificationEntry; |
206 | begin |
207 | begin |
207 | result := TUD2IdentificationEntry.Create(IdStr, Self); |
208 | result := TUD2IdentificationEntry.Create(IdStr, Self); |
208 | DetectedIdentifications.Add(result); |
209 | DetectedIdentifications.Add(result); |
209 | end; |
210 | end; |
210 | 211 | ||
211 | destructor TUD2Plugin.Destroy; |
212 | destructor TUD2Plugin.Destroy; |
212 | begin |
213 | begin |
213 | DetectedIdentifications.Free; |
214 | DetectedIdentifications.Free; |
214 | inherited; |
215 | inherited; |
215 | end; |
216 | end; |
216 | 217 | ||
217 | constructor TUD2Plugin.Create; |
218 | constructor TUD2Plugin.Create; |
218 | begin |
219 | begin |
219 | inherited Create; |
220 | inherited Create; |
220 | FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true); |
221 | FDetectedIdentifications := TObjectList{<TUD2IdentificationEntry>}.Create(true); |
221 | end; |
222 | end; |
222 | 223 | ||
223 | function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean; |
224 | function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings; var outIDs: TArrayOfString): boolean; |
224 | var |
225 | var |
225 | ude: TUD2IdentificationEntry; |
226 | ude: TUD2IdentificationEntry; |
226 | i: integer; |
227 | i: integer; |
227 | id: string; |
228 | id: string; |
228 | l: integer; |
229 | l: integer; |
229 | begin |
230 | begin |
230 | result := false; |
231 | result := false; |
231 | 232 | ||
232 | SetLength(outIDs, 0); |
233 | SetLength(outIDs, 0); |
233 | 234 | ||
234 | for i := 0 to FDetectedIdentifications.Count-1 do |
235 | for i := 0 to FDetectedIdentifications.Count-1 do |
235 | begin |
236 | begin |
236 | ude := FDetectedIdentifications.Items[i] as TUD2IdentificationEntry; |
237 | ude := FDetectedIdentifications.Items[i] as TUD2IdentificationEntry; |
237 | if ude.dynamicDataUsed and (ude.dynamicData = dynamicData) then |
238 | if ude.dynamicDataUsed and (ude.dynamicData = dynamicData) then |
238 | begin |
239 | begin |
239 | l := Length(outIDs); |
240 | l := Length(outIDs); |
240 | SetLength(outIDs, l+1); |
241 | SetLength(outIDs, l+1); |
241 | outIDs[l] := ude.FIdentificationString; |
242 | outIDs[l] := ude.FIdentificationString; |
242 | end; |
243 | end; |
243 | end; |
244 | end; |
244 | 245 | ||
245 | // The dynamic content was already evaluated (and therefore is already added in FDetectedIdentifications). |
246 | // The dynamic content was already evaluated (and therefore is already added in FDetectedIdentifications). |
246 | if Length(outIDs) > 0 then exit; |
247 | if Length(outIDs) > 0 then exit; |
247 | 248 | ||
248 | outIDs := GetDynamicRequestResult(dynamicData, AErrorOut); |
249 | outIDs := GetDynamicRequestResult(dynamicData, AErrorOut); |
249 | 250 | ||
250 | for i := 0 to Length(outIDs)-1 do |
251 | for i := 0 to Length(outIDs)-1 do |
251 | begin |
252 | begin |
252 | id := outIDs[i]; |
253 | id := outIDs[i]; |
253 | 254 | ||
254 | ude := AddIdentification(id); |
255 | ude := AddIdentification(id); |
255 | ude.dynamicDataUsed := true; |
256 | ude.dynamicDataUsed := true; |
256 | ude.dynamicData := dynamicData; |
257 | ude.dynamicData := dynamicData; |
257 | 258 | ||
258 | result := true; |
259 | result := true; |
259 | end; |
260 | end; |
260 | end; |
261 | end; |
261 | 262 | ||
262 | function TUD2Plugin.GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString; |
263 | function TUD2Plugin.GetDynamicRequestResult(dynamicData: WideString; AErrorOut: TStrings=nil): TArrayOfString; |
263 | var |
264 | var |
264 | lngID: LANGID; |
265 | lngID: LANGID; |
265 | loader: TUD2PluginLoader; |
266 | loader: TUD2PluginLoader; |
266 | begin |
267 | begin |
267 | lngID := GetSystemDefaultLangID; |
268 | lngID := GetSystemDefaultLangID; |
268 | 269 | ||
269 | loader := TUD2PluginLoader.Create(false, PluginDLL, lngid, true, dynamicData); |
270 | loader := TUD2PluginLoader.Create(false, PluginDLL, lngid, true, dynamicData); |
270 | try |
271 | try |
271 | loader.WaitFor; |
272 | loader.WaitFor; |
272 | result := loader.ResultIdentifiers; |
273 | result := loader.ResultIdentifiers; |
273 | if Assigned(AErrorOut) then |
274 | if Assigned(AErrorOut) then |
274 | begin |
275 | begin |
275 | AErrorOut.AddStrings(loader.Errors); |
276 | AErrorOut.AddStrings(loader.Errors); |
276 | end; |
277 | end; |
277 | 278 | ||
278 | // TODO: Use assign() instead? or allow TUD2PluginLoader to write the TPlugin object directly? |
279 | // TODO: Use assign() instead? or allow TUD2PluginLoader to write the TPlugin object directly? |
279 | // Should we even overwrite the current plugin data, or return the new plugin? |
280 | // Should we even overwrite the current plugin data, or return the new plugin? |
280 | FIdentificationProcedureStatusCode := loader.plugin.IdentificationProcedureStatusCode; |
281 | FIdentificationProcedureStatusCode := loader.plugin.IdentificationProcedureStatusCode; |
281 | FIdentificationProcedureStatusCodeDescribed := loader.plugin.IdentificationProcedureStatusCodeDescribed; |
282 | FIdentificationProcedureStatusCodeDescribed := loader.plugin.IdentificationProcedureStatusCodeDescribed; |
282 | FOSNotSupportedEnforced := loader.plugin.OSNotSupportedEnforced; |
283 | FOSNotSupportedEnforced := loader.plugin.OSNotSupportedEnforced; |
283 | FLoadingTime := loader.Plugin.LoadingTime; |
284 | FLoadingTime := loader.Plugin.LoadingTime; |
284 | 285 | ||
285 | finally |
286 | finally |
286 | if Assigned(loader.Plugin) then FreeAndNil(loader.Plugin); |
287 | if Assigned(loader.Plugin) then FreeAndNil(loader.Plugin); |
287 | loader.Free; |
288 | loader.Free; |
288 | end; |
289 | end; |
289 | end; |
290 | end; |
290 | 291 | ||
291 | function TUD2Plugin.EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
292 | function TUD2Plugin.EqualsMethodNameOrGuid(idMethodNameOrGUID: string): boolean; |
292 | begin |
293 | begin |
293 | result := SameText(IdentificationMethodName, idMethodNameOrGUID) or |
294 | result := SameText(IdentificationMethodName, idMethodNameOrGUID) or |
294 | SameText(GUIDToString(PluginGUID), idMethodNameOrGUID) |
295 | SameText(GUIDToString(PluginGUID), idMethodNameOrGUID) |
295 | end; |
296 | end; |
296 | 297 | ||
297 | function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean; |
298 | function TUD2Plugin.InvokeDynamicCheck(dynamicData: WideString; AErrorOut: TStrings): boolean; |
298 | var |
299 | var |
299 | dummy: TArrayOfString; |
300 | dummy: TArrayOfString; |
300 | begin |
301 | begin |
301 | result := InvokeDynamicCheck(dynamicData, AErrorOut, dummy) |
302 | result := InvokeDynamicCheck(dynamicData, AErrorOut, dummy) |
302 | end; |
303 | end; |
303 | 304 | ||
304 | { TUD2IdentificationEntry } |
305 | { TUD2IdentificationEntry } |
305 | 306 | ||
306 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
307 | procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
307 | var |
308 | var |
308 | cond: TUD2TDFCondition; |
309 | cond: TUD2TDFCondition; |
309 | begin |
310 | begin |
310 | cond.idMethodName := Plugin.IdentificationMethodName; |
311 | cond.idMethodName := Plugin.IdentificationMethodName; |
311 | cond.idStr := IdentificationString; |
312 | cond.idStr := IdentificationString; |
312 | cond.dynamicDataUsed := DynamicDataUsed; |
313 | cond.dynamicDataUsed := DynamicDataUsed; |
313 | cond.dynamicData := DynamicData; |
314 | cond.dynamicData := DynamicData; |
314 | sl.Add(UD2_CondToStr(cond)); |
315 | sl.Add(UD2_CondToStr(cond)); |
315 | 316 | ||
316 | cond.idMethodName := Plugin.PluginGUIDString; |
317 | cond.idMethodName := Plugin.PluginGUIDString; |
317 | sl.Add(UD2_CondToStr(cond)); |
318 | sl.Add(UD2_CondToStr(cond)); |
318 | end; |
319 | end; |
319 | 320 | ||
320 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
321 | constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
321 | APlugin: TUD2Plugin); |
322 | APlugin: TUD2Plugin); |
322 | begin |
323 | begin |
323 | inherited Create; |
324 | inherited Create; |
324 | 325 | ||
325 | // TODO: We need to do this, because ReadSectionValues strips the names of the name-value pairs... |
326 | // TODO: We need to do this, because ReadSectionValues strips the names of the name-value pairs... |
326 | // We should correct ReadSectionValues... |
327 | // We should correct ReadSectionValues... |
327 | // Example: DriveSerial(c:):2SHSWNHA010807 X =calc.exe |
328 | // Example: DriveSerial(c:):2SHSWNHA010807 X =calc.exe |
328 | // ReadSectionValues will return "DriveSerial(c:):2SHSWNHA010807 X=calc.exe" |
329 | // ReadSectionValues will return "DriveSerial(c:):2SHSWNHA010807 X=calc.exe" |
329 | AIdentificationString := Trim(AIdentificationString); |
330 | AIdentificationString := Trim(AIdentificationString); |
330 | 331 | ||
331 | FIdentificationString := AIdentificationString; |
332 | FIdentificationString := AIdentificationString; |
332 | FPlugin := APlugin; |
333 | FPlugin := APlugin; |
333 | end; |
334 | end; |
- | 335 | ||
- | 336 | function TUD2IdentificationEntry.GetConditionString(MethodnameAsGUID: boolean=false): TUD2TDFCondition; |
|
- | 337 | begin |
|
- | 338 | if MethodnameAsGUID then |
|
- | 339 | Result.idMethodName := GUIDToString(Self.Plugin.PluginGUID) |
|
- | 340 | else |
|
- | 341 | Result.idMethodName := Self.Plugin.IdentificationMethodName; |
|
- | 342 | ||
- | 343 | Result.idStr := Self.IdentificationString; |
|
- | 344 | Result.dynamicDataUsed := Self.DynamicDataUsed; |
|
- | 345 | Result.dynamicData := Self.DynamicData; |
|
- | 346 | Result.caseSensitive := false; |
|
- | 347 | end; |
|
334 | 348 | ||
335 | { TUD2 } |
349 | { TUD2 } |
336 | 350 | ||
337 | procedure TUD2.HandlePluginDir(APluginDir, AFileMask: string); |
351 | procedure TUD2.HandlePluginDir(APluginDir, AFileMask: string); |
338 | Var |
352 | Var |
339 | SR: TSearchRec; |
353 | SR: TSearchRec; |
340 | path: string; |
354 | path: string; |
341 | pluginLoader: TUD2PluginLoader; |
355 | pluginLoader: TUD2PluginLoader; |
342 | tob: TObjectList{<TUD2PluginLoader>}; |
356 | tob: TObjectList{<TUD2PluginLoader>}; |
343 | i: integer; |
357 | i: integer; |
344 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
358 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
345 | sPluginID, prevDLL: string; |
359 | sPluginID, prevDLL: string; |
346 | {$ENDIF} |
360 | {$ENDIF} |
347 | lngid: LANGID; |
361 | lngid: LANGID; |
348 | resourcestring |
362 | resourcestring |
349 | LNG_PLUGINS_SAME_GUID = 'Attention: The plugin "%s" and the plugin "%s" have the same identification GUID. The latter will not be loaded.'; |
363 | LNG_PLUGINS_SAME_GUID = 'Attention: The plugin "%s" and the plugin "%s" have the same identification GUID. The latter will not be loaded.'; |
350 | begin |
364 | begin |
351 | tob := TObjectList{<TUD2PluginLoader>}.Create; |
365 | tob := TObjectList{<TUD2PluginLoader>}.Create; |
352 | try |
366 | try |
353 | tob.OwnsObjects := false; |
367 | tob.OwnsObjects := false; |
354 | 368 | ||
355 | lngID := GetSystemDefaultLangID; |
369 | lngID := GetSystemDefaultLangID; |
356 | 370 | ||
357 | path := APluginDir; |
371 | path := APluginDir; |
358 | if path <> '' then path := IncludeTrailingPathDelimiter(path); |
372 | if path <> '' then path := IncludeTrailingPathDelimiter(path); |
359 | 373 | ||
360 | if FindFirst(path + AFileMask, 0, SR) = 0 then |
374 | if FindFirst(path + AFileMask, 0, SR) = 0 then |
361 | begin |
375 | begin |
362 | try |
376 | try |
363 | repeat |
377 | repeat |
364 | try |
378 | try |
365 | tob.Add(TUD2PluginLoader.Create(false, path + sr.Name, lngid, false, '')); |
379 | tob.Add(TUD2PluginLoader.Create(false, path + sr.Name, lngid, false, '')); |
366 | except |
380 | except |
367 | on E: Exception do |
381 | on E: Exception do |
368 | begin |
382 | begin |
369 | MessageDlg(E.Message, mtError, [mbOK], 0); |
383 | MessageDlg(E.Message, mtError, [mbOK], 0); |
370 | end; |
384 | end; |
371 | end; |
385 | end; |
372 | until FindNext(SR) <> 0; |
386 | until FindNext(SR) <> 0; |
373 | finally |
387 | finally |
374 | FindClose(SR); |
388 | FindClose(SR); |
375 | end; |
389 | end; |
376 | end; |
390 | end; |
377 | 391 | ||
378 | for i := 0 to tob.count-1 do |
392 | for i := 0 to tob.count-1 do |
379 | begin |
393 | begin |
380 | pluginLoader := tob.items[i] as TUD2PluginLoader; |
394 | pluginLoader := tob.items[i] as TUD2PluginLoader; |
381 | pluginLoader.WaitFor; |
395 | pluginLoader.WaitFor; |
382 | Errors.AddStrings(pluginLoader.Errors); |
396 | Errors.AddStrings(pluginLoader.Errors); |
383 | if Assigned(pluginLoader.Plugin) then |
397 | if Assigned(pluginLoader.Plugin) then |
384 | begin |
398 | begin |
385 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
399 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
386 | if pluginLoader.Plugin.PluginGUIDSet then |
400 | if pluginLoader.Plugin.PluginGUIDSet then |
387 | begin |
401 | begin |
388 | sPluginID := GUIDToString(pluginLoader.Plugin.PluginGUID); |
402 | sPluginID := GUIDToString(pluginLoader.Plugin.PluginGUID); |
389 | prevDLL := FGUIDLookup.Values[sPluginID]; |
403 | prevDLL := FGUIDLookup.Values[sPluginID]; |
390 | if (prevDLL <> '') and (prevDLL <> pluginLoader.Plugin.PluginDLL) then |
404 | if (prevDLL <> '') and (prevDLL <> pluginLoader.Plugin.PluginDLL) then |
391 | begin |
405 | begin |
392 | Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.Plugin.PluginDLL])); |
406 | Errors.Add(Format(LNG_PLUGINS_SAME_GUID, [prevDLL, pluginLoader.Plugin.PluginDLL])); |
393 | pluginLoader.Plugin.Free; |
407 | pluginLoader.Plugin.Free; |
394 | end |
408 | end |
395 | else |
409 | else |
396 | begin |
410 | begin |
397 | FGUIDLookup.Values[sPluginID] := pluginLoader.Plugin.PluginDLL; |
411 | FGUIDLookup.Values[sPluginID] := pluginLoader.Plugin.PluginDLL; |
398 | LoadedPlugins.Add(pluginLoader.Plugin); |
412 | LoadedPlugins.Add(pluginLoader.Plugin); |
399 | end; |
413 | end; |
400 | end |
414 | end |
401 | else |
415 | else |
402 | begin |
416 | begin |
403 | LoadedPlugins.Add(pluginLoader.Plugin); |
417 | LoadedPlugins.Add(pluginLoader.Plugin); |
404 | end; |
418 | end; |
405 | {$ELSE} |
419 | {$ELSE} |
406 | LoadedPlugins.Add(pluginLoader.Plugin); |
420 | LoadedPlugins.Add(pluginLoader.Plugin); |
407 | {$ENDIF} |
421 | {$ENDIF} |
408 | end; |
422 | end; |
409 | pluginLoader.Free; |
423 | pluginLoader.Free; |
410 | end; |
424 | end; |
411 | finally |
425 | finally |
412 | tob.free; |
426 | tob.free; |
413 | end; |
427 | end; |
414 | end; |
428 | end; |
415 | 429 | ||
416 | destructor TUD2.Destroy; |
430 | destructor TUD2.Destroy; |
417 | begin |
431 | begin |
418 | FIniFile.Free; |
432 | FIniFile.Free; |
419 | FLoadedPlugins.Free; |
433 | FLoadedPlugins.Free; |
420 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
434 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
421 | FGUIDLookup.Free; |
435 | FGUIDLookup.Free; |
422 | {$ENDIF} |
436 | {$ENDIF} |
423 | FErrors.Free; |
437 | FErrors.Free; |
424 | end; |
438 | end; |
425 | 439 | ||
426 | constructor TUD2.Create(AIniFileName: string); |
440 | constructor TUD2.Create(AIniFileName: string); |
427 | begin |
441 | begin |
428 | FIniFileName := AIniFileName; |
442 | FIniFileName := AIniFileName; |
429 | FLoadedPlugins := TObjectList{<TUD2Plugin>}.Create(true); |
443 | FLoadedPlugins := TObjectList{<TUD2Plugin>}.Create(true); |
430 | FIniFile := TMemIniFile.Create(IniFileName); |
444 | FIniFile := TMemIniFile.Create(IniFileName); |
431 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
445 | {$IFDEF CHECK_FOR_SAME_PLUGIN_GUID} |
432 | FGUIDLookup := TStringList.Create; |
446 | FGUIDLookup := TStringList.Create; |
433 | {$ENDIF} |
447 | {$ENDIF} |
434 | FErrors := TStringList.Create; |
448 | FErrors := TStringList.Create; |
435 | end; |
449 | end; |
436 | 450 | ||
437 | function TUD2.GetTaskName(AShortTaskName: string): string; |
451 | function TUD2.GetTaskName(AShortTaskName: string): string; |
438 | resourcestring |
452 | resourcestring |
439 | LNG_NO_DESCRIPTION = '(%s)'; |
453 | LNG_NO_DESCRIPTION = '(%s)'; |
440 | begin |
454 | begin |
441 | result := FIniFile.ReadString(AShortTaskName, UD2_TagDescription, Format(LNG_NO_DESCRIPTION, [AShortTaskName])); |
455 | result := FIniFile.ReadString(AShortTaskName, UD2_TagDescription, Format(LNG_NO_DESCRIPTION, [AShortTaskName])); |
442 | end; |
456 | end; |
443 | 457 | ||
444 | procedure TUD2.GetTaskListing(outSL: TStrings); |
458 | procedure TUD2.GetTaskListing(outSL: TStrings); |
445 | var |
459 | var |
446 | sl: TStringList; |
460 | sl: TStringList; |
447 | i: integer; |
461 | i: integer; |
448 | desc: string; |
462 | desc: string; |
449 | begin |
463 | begin |
450 | sl := TStringList.Create; |
464 | sl := TStringList.Create; |
451 | try |
465 | try |
452 | FIniFile.ReadSections(sl); |
466 | FIniFile.ReadSections(sl); |
453 | for i := 0 to sl.Count-1 do |
467 | for i := 0 to sl.Count-1 do |
454 | begin |
468 | begin |
455 | desc := GetTaskName(sl.Strings[i]); |
469 | desc := GetTaskName(sl.Strings[i]); |
456 | outSL.Values[sl.Strings[i]] := desc; |
470 | outSL.Values[sl.Strings[i]] := desc; |
457 | end; |
471 | end; |
458 | finally |
472 | finally |
459 | sl.Free; |
473 | sl.Free; |
460 | end; |
474 | end; |
461 | end; |
475 | end; |
462 | 476 | ||
463 | function TUD2.TaskExists(ShortTaskName: string): boolean; |
477 | function TUD2.TaskExists(ShortTaskName: string): boolean; |
464 | begin |
478 | begin |
465 | result := FIniFile.SectionExists(ShortTaskName); |
479 | result := FIniFile.SectionExists(ShortTaskName); |
466 | end; |
480 | end; |
467 | 481 | ||
468 | function TUD2.ReadMetatagString(ShortTaskName, MetatagName: string; DefaultVal: string): string; |
482 | function TUD2.ReadMetatagString(ShortTaskName, MetatagName: string; DefaultVal: string): string; |
469 | begin |
483 | begin |
470 | result := IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal); |
484 | result := IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal); |
471 | end; |
485 | end; |
472 | 486 | ||
473 | function TUD2.ReadMetatagBool(ShortTaskName, MetatagName: string; DefaultVal: string): boolean; |
487 | function TUD2.ReadMetatagBool(ShortTaskName, MetatagName: string; DefaultVal: string): boolean; |
474 | begin |
488 | begin |
475 | // DefaultVal is a string, because we want to allow an empty string, in case the |
489 | // DefaultVal is a string, because we want to allow an empty string, in case the |
476 | // user wishes an Exception in case the string is not a valid boolean string |
490 | // user wishes an Exception in case the string is not a valid boolean string |
477 | result := BetterInterpreteBool(IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal)); |
491 | result := BetterInterpreteBool(IniFile.ReadString(ShortTaskName, MetatagName, DefaultVal)); |
478 | end; |
492 | end; |
479 | 493 | ||
480 | (* |
494 | (* |
481 | 495 | ||
482 | NAMING EXAMPLE: $CASESENSITIVE$ComputerName(dynXYZ):ABC&&User:John=calc.exe$RIOD$ |
496 | NAMING EXAMPLE: $CASESENSITIVE$ComputerName(dynXYZ):ABC&&User:John=calc.exe$RIOD$ |
483 | 497 | ||
484 | idTerm: ComputerName(dynXYZ):ABC&&User:John |
498 | idTerm: ComputerName(dynXYZ):ABC&&User:John |
485 | idName: ComputerName:ABC |
499 | idName: ComputerName:ABC |
486 | IdMethodName: ComputerName |
500 | IdMethodName: ComputerName |
487 | IdStr ABC |
501 | IdStr ABC |
488 | cmd: calc.exe |
502 | cmd: calc.exe |
489 | dynamicData: dynXYZ |
503 | dynamicData: dynXYZ |
490 | 504 | ||
491 | *) |
505 | *) |
492 | 506 | ||
493 | procedure TUD2.GetAllDetectedIDs(outSL: TStrings); |
507 | procedure TUD2.GetAllDetectedIDs(outSL: TStrings); |
494 | var |
508 | var |
495 | i, j: integer; |
509 | i, j: integer; |
496 | pl: TUD2Plugin; |
510 | pl: TUD2Plugin; |
497 | ude: TUD2IdentificationEntry; |
511 | ude: TUD2IdentificationEntry; |
498 | begin |
512 | begin |
499 | for i := 0 to LoadedPlugins.Count-1 do |
513 | for i := 0 to LoadedPlugins.Count-1 do |
500 | begin |
514 | begin |
501 | pl := LoadedPlugins.Items[i] as TUD2Plugin; |
515 | pl := LoadedPlugins.Items[i] as TUD2Plugin; |
502 | for j := 0 to pl.DetectedIdentifications.Count-1 do |
516 | for j := 0 to pl.DetectedIdentifications.Count-1 do |
503 | begin |
517 | begin |
504 | ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry; |
518 | ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry; |
505 | ude.GetIdNames(outSL); |
519 | ude.GetIdNames(outSL); |
506 | end; |
520 | end; |
507 | end; |
521 | end; |
508 | end; |
522 | end; |
509 | 523 | ||
510 | function TUD2.FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; |
524 | function TUD2.FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; |
511 | begin |
525 | begin |
512 | result := FulfilsEverySubterm(UD2_CondsToStr(conds), slIdNames, AErrorOut); |
526 | result := FulfilsEverySubterm(UD2_CondsToStr(conds), slIdNames, AErrorOut); |
513 | end; |
527 | end; |
514 | 528 | ||
515 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; |
529 | function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): boolean; |
516 | var |
530 | var |
517 | i: integer; |
531 | i: integer; |
518 | p: TUD2Plugin; |
532 | p: TUD2Plugin; |
519 | cleanUpStringList: boolean; |
533 | cleanUpStringList: boolean; |
520 | conds: TUD2TDFConditionArray; |
534 | conds: TUD2TDFConditionArray; |
521 | cond: TUD2TDFCondition; |
535 | cond: TUD2TDFCondition; |
522 | idName: string; |
536 | idName: string; |
523 | begin |
537 | begin |
524 | {$IFDEF NO_CONDITIONS_IS_FAILURE} |
538 | {$IFDEF NO_CONDITIONS_IS_FAILURE} |
525 | if idTerm = '' then |
539 | if idTerm = '' then |
526 | begin |
540 | begin |
527 | SetLength(conds, 0); |
541 | SetLength(conds, 0); |
528 | result := false; |
542 | result := false; |
529 | Exit; |
543 | Exit; |
530 | end; |
544 | end; |
531 | {$ENDIF} |
545 | {$ENDIF} |
532 | 546 | ||
533 | cleanUpStringList := slIdNames = nil; |
547 | cleanUpStringList := slIdNames = nil; |
534 | try |
548 | try |
535 | if cleanUpStringList then |
549 | if cleanUpStringList then |
536 | begin |
550 | begin |
537 | slIdNames := TStringList.Create; |
551 | slIdNames := TStringList.Create; |
538 | GetAllDetectedIDs(slIdNames); |
552 | GetAllDetectedIDs(slIdNames); |
539 | end; |
553 | end; |
540 | 554 | ||
541 | conds := UD2P_ParseConditions(idTerm); |
555 | conds := UD2P_ParseConditions(idTerm); |
542 | 556 | ||
543 | result := true; |
557 | result := true; |
544 | for i := Low(conds) to High(conds) do |
558 | for i := Low(conds) to High(conds) do |
545 | begin |
559 | begin |
546 | cond := conds[i]; |
560 | cond := conds[i]; |
547 | 561 | ||
548 | if cond.dynamicDataUsed then |
562 | if cond.dynamicDataUsed then |
549 | begin |
563 | begin |
550 | p := FindPluginByMethodNameOrGuid(cond.idMethodName); |
564 | p := FindPluginByMethodNameOrGuid(cond.idMethodName); |
551 | if Assigned(p) then |
565 | if Assigned(p) then |
552 | begin |
566 | begin |
553 | if p.InvokeDynamicCheck(cond.dynamicData, AErrorOut) then |
567 | if p.InvokeDynamicCheck(cond.dynamicData, AErrorOut) then |
554 | begin |
568 | begin |
555 | // Reload the identifications |
569 | // Reload the identifications |
556 | slIdNames.Clear; |
570 | slIdNames.Clear; |
557 | GetAllDetectedIDs(slIdNames); |
571 | GetAllDetectedIDs(slIdNames); |
558 | end; |
572 | end; |
559 | end; |
573 | end; |
560 | end; |
574 | end; |
561 | 575 | ||
562 | idName := UD2_CondToStr(cond); |
576 | idName := UD2_CondToStr(cond); |
563 | 577 | ||
564 | if (not cond.caseSensitive and (slIdNames.IndexOf(idName) = -1)) or |
578 | if (not cond.caseSensitive and (slIdNames.IndexOf(idName) = -1)) or |
565 | (cond.caseSensitive and (IndexOf_CS(slIdNames, idName) = -1)) then |
579 | (cond.caseSensitive and (IndexOf_CS(slIdNames, idName) = -1)) then |
566 | begin |
580 | begin |
567 | result := false; |
581 | result := false; |
568 | break; |
582 | break; |
569 | end; |
583 | end; |
570 | end; |
584 | end; |
571 | finally |
585 | finally |
572 | if cleanUpStringList and Assigned(slIdNames) then |
586 | if cleanUpStringList and Assigned(slIdNames) then |
573 | slIdNames.Free; |
587 | slIdNames.Free; |
574 | end; |
588 | end; |
575 | end; |
589 | end; |
576 | 590 | ||
577 | function TUD2.FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
591 | function TUD2.FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
578 | var |
592 | var |
579 | i: integer; |
593 | i: integer; |
580 | p: TUD2Plugin; |
594 | p: TUD2Plugin; |
581 | begin |
595 | begin |
582 | result := nil; |
596 | result := nil; |
583 | for i := 0 to LoadedPlugins.Count-1 do |
597 | for i := 0 to LoadedPlugins.Count-1 do |
584 | begin |
598 | begin |
585 | p := LoadedPlugins.Items[i] as TUD2Plugin; |
599 | p := LoadedPlugins.Items[i] as TUD2Plugin; |
586 | 600 | ||
587 | if p.EqualsMethodNameOrGuid(idMethodName) then |
601 | if p.EqualsMethodNameOrGuid(idMethodName) then |
588 | begin |
602 | begin |
589 | result := p; |
603 | result := p; |
590 | Exit; |
604 | Exit; |
591 | end; |
605 | end; |
592 | end; |
606 | end; |
593 | end; |
607 | end; |
594 | 608 | ||
595 | function TUD2.GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray; |
609 | function TUD2.GetCommandList(ShortTaskName: string; AErrorOut: TStrings=nil): TUD2CommandArray; |
596 | var |
610 | var |
597 | i, j, l: integer; |
611 | i, j, l: integer; |
598 | slSV, slIdNames: TStrings; |
612 | slSV, slIdNames: TStrings; |
599 | tmpCmds: TUD2CommandArray; |
613 | tmpCmds: TUD2CommandArray; |
600 | begin |
614 | begin |
601 | SetLength(result, 0); |
615 | SetLength(result, 0); |
602 | SetLength(tmpCmds, 0); |
616 | SetLength(tmpCmds, 0); |
603 | 617 | ||
604 | slIdNames := TStringList.Create; |
618 | slIdNames := TStringList.Create; |
605 | try |
619 | try |
606 | GetAllDetectedIDs(slIdNames); |
620 | GetAllDetectedIDs(slIdNames); |
607 | 621 | ||
608 | slSV := TStringList.Create; |
622 | slSV := TStringList.Create; |
609 | try |
623 | try |
610 | FIniFile.ReadSectionValues(ShortTaskName, slSV); |
624 | FIniFile.ReadSectionValues(ShortTaskName, slSV); |
611 | for i := 0 to slSV.Count-1 do |
625 | for i := 0 to slSV.Count-1 do |
612 | begin |
626 | begin |
613 | tmpCmds := CheckTerm(slSV.Strings[i], slIdNames, AErrorOut); |
627 | tmpCmds := CheckTerm(slSV.Strings[i], slIdNames, AErrorOut); |
614 | for j := Low(tmpCmds) to High(tmpCmds) do |
628 | for j := Low(tmpCmds) to High(tmpCmds) do |
615 | begin |
629 | begin |
616 | l := Length(result); |
630 | l := Length(result); |
617 | SetLength(result, l+1); |
631 | SetLength(result, l+1); |
618 | result[l] := tmpCmds[j]; |
632 | result[l] := tmpCmds[j]; |
619 | end; |
633 | end; |
620 | end; |
634 | end; |
621 | finally |
635 | finally |
622 | slSV.Free; |
636 | slSV.Free; |
623 | end; |
637 | end; |
624 | finally |
638 | finally |
625 | slIdNames.Free; |
639 | slIdNames.Free; |
626 | end; |
640 | end; |
627 | end; |
641 | end; |
628 | 642 | ||
629 | function TUD2.CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray; |
643 | function TUD2.CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil; AErrorOut: TStrings=nil): TUD2CommandArray; |
630 | var |
644 | var |
631 | slIdNamesCreated: boolean; |
645 | slIdNamesCreated: boolean; |
632 | ent: TUD2TDFEntry; |
646 | ent: TUD2TDFEntry; |
633 | begin |
647 | begin |
634 | SetLength(result, 0); |
648 | SetLength(result, 0); |
635 | 649 | ||
636 | slIdNamesCreated := false; |
650 | slIdNamesCreated := false; |
637 | try |
651 | try |
638 | if not Assigned(slIdNames) then |
652 | if not Assigned(slIdNames) then |
639 | begin |
653 | begin |
640 | slIdNamesCreated := true; |
654 | slIdNamesCreated := true; |
641 | slIdNames := TStringList.Create; |
655 | slIdNames := TStringList.Create; |
642 | GetAllDetectedIDs(slIdNames); |
656 | GetAllDetectedIDs(slIdNames); |
643 | end; |
657 | end; |
644 | 658 | ||
645 | if not UD2P_ParseTdfLine(idTermAndCmd, ent) then Exit; |
659 | if not UD2P_ParseTdfLine(idTermAndCmd, ent) then Exit; |
646 | if FulfilsEverySubterm(ent.ids, slIdNames, AErrorOut) then |
660 | if FulfilsEverySubterm(ent.ids, slIdNames, AErrorOut) then |
647 | begin |
661 | begin |
648 | result := ent.commands; |
662 | result := ent.commands; |
649 | end; |
663 | end; |
650 | finally |
664 | finally |
651 | if slIdNamesCreated then slIdNames.Free; |
665 | if slIdNamesCreated then slIdNames.Free; |
652 | end; |
666 | end; |
653 | end; |
667 | end; |
654 | 668 | ||
655 | { TUD2PluginLoader } |
669 | { TUD2PluginLoader } |
656 | 670 | ||
657 | procedure TUD2PluginLoader.Execute; |
671 | procedure TUD2PluginLoader.Execute; |
658 | begin |
672 | begin |
659 | inherited; |
673 | inherited; |
660 | 674 | ||
661 | HandleDLL; |
675 | HandleDLL; |
662 | end; |
676 | end; |
663 | 677 | ||
664 | constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
678 | constructor TUD2PluginLoader.Create(Suspended: boolean; DLL: string; alngid: LANGID; useDynamicData: boolean; dynamicData: WideString); |
665 | begin |
679 | begin |
666 | inherited Create(Suspended); |
680 | inherited Create(Suspended); |
667 | dllfile := dll; |
681 | dllfile := dll; |
668 | Plugin := nil; |
682 | Plugin := nil; |
669 | Errors := TStringList.Create; |
683 | Errors := TStringList.Create; |
670 | lngid := alngid; |
684 | lngid := alngid; |
671 | self.useDynamicData := useDynamicData; |
685 | self.useDynamicData := useDynamicData; |
672 | Self.dynamicData := dynamicData; |
686 | Self.dynamicData := dynamicData; |
673 | end; |
687 | end; |
674 | 688 | ||
675 | destructor TUD2PluginLoader.Destroy; |
689 | destructor TUD2PluginLoader.Destroy; |
676 | begin |
690 | begin |
677 | Errors.Free; |
691 | Errors.Free; |
678 | inherited; |
692 | inherited; |
679 | end; |
693 | end; |
680 | 694 | ||
681 | function TUD2PluginLoader.HandleDLL: boolean; |
695 | function TUD2PluginLoader.HandleDLL: boolean; |
682 | var |
696 | var |
683 | sIdentifier: WideString; |
697 | sIdentifier: WideString; |
684 | buf: array[0..cchBufferSize-1] of WideChar; |
698 | buf: array[0..cchBufferSize-1] of WideChar; |
685 | pluginInterfaceID: TGUID; |
699 | pluginInterfaceID: TGUID; |
686 | dllHandle: Cardinal; |
700 | dllHandle: Cardinal; |
687 | fPluginInterfaceID: TFuncPluginInterfaceID; |
701 | fPluginInterfaceID: TFuncPluginInterfaceID; |
688 | fPluginIdentifier: TFuncPluginIdentifier; |
702 | fPluginIdentifier: TFuncPluginIdentifier; |
689 | fPluginNameW: TFuncPluginNameW; |
703 | fPluginNameW: TFuncPluginNameW; |
690 | fPluginVendorW: TFuncPluginVendorW; |
704 | fPluginVendorW: TFuncPluginVendorW; |
691 | fPluginVersionW: TFuncPluginVersionW; |
705 | fPluginVersionW: TFuncPluginVersionW; |
692 | fIdentificationMethodNameW: TFuncIdentificationMethodNameW; |
706 | fIdentificationMethodNameW: TFuncIdentificationMethodNameW; |
693 | fIdentificationStringW: TFuncIdentificationStringW; |
707 | fIdentificationStringW: TFuncIdentificationStringW; |
694 | fDynamicIdentificationStringW: TFuncDynamicIdentificationStringW; |
708 | fDynamicIdentificationStringW: TFuncDynamicIdentificationStringW; |
695 | fCheckLicense: TFuncCheckLicense; |
709 | fCheckLicense: TFuncCheckLicense; |
696 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
710 | fDescribeOwnStatusCodeW: TFuncDescribeOwnStatusCodeW; |
697 | statusCode: UD2_STATUS; |
711 | statusCode: UD2_STATUS; |
698 | i: integer; |
712 | i: integer; |
699 | starttime, endtime, time: cardinal; |
713 | starttime, endtime, time: cardinal; |
700 | bakErrorMode: DWORD; |
714 | bakErrorMode: DWORD; |
701 | err: DWORD; |
715 | err: DWORD; |
702 | 716 | ||
703 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
717 | function _ErrorLookup(statusCode: UD2_STATUS): WideString; |
704 | var |
718 | var |
705 | ret: BOOL; |
719 | ret: BOOL; |
706 | buf: array[0..cchBufferSize-1] of WideChar; |
720 | buf: array[0..cchBufferSize-1] of WideChar; |
707 | begin |
721 | begin |
708 | if Assigned(fDescribeOwnStatusCodeW) then |
722 | if Assigned(fDescribeOwnStatusCodeW) then |
709 | begin |
723 | begin |
710 | ZeroMemory(@buf, cchBufferSize); |
724 | ZeroMemory(@buf, cchBufferSize); |
711 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
725 | ret := fDescribeOwnStatusCodeW(@buf, cchBufferSize, statusCode, lngID); |
712 | if ret then |
726 | if ret then |
713 | begin |
727 | begin |
714 | result := PWideChar(@buf); |
728 | result := PWideChar(@buf); |
715 | Exit; |
729 | Exit; |
716 | end; |
730 | end; |
717 | end; |
731 | end; |
718 | result := TUD2.GenericErrorLookup(statusCode); |
732 | result := TUD2.GenericErrorLookup(statusCode); |
719 | end; |
733 | end; |
720 | 734 | ||
721 | function _ApplyCompatibilityGUID: boolean; |
735 | function _ApplyCompatibilityGUID: boolean; |
722 | var |
736 | var |
723 | iniConfig: TIniFile; |
737 | iniConfig: TIniFile; |
724 | sOverrideGUID: string; |
738 | sOverrideGUID: string; |
725 | sPluginConfigFile: string; |
739 | sPluginConfigFile: string; |
726 | begin |
740 | begin |
727 | result := false; |
741 | result := false; |
728 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
742 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
729 | if FileExists(sPluginConfigFile) then |
743 | if FileExists(sPluginConfigFile) then |
730 | begin |
744 | begin |
731 | iniConfig := TIniFile.Create(sPluginConfigFile); |
745 | iniConfig := TIniFile.Create(sPluginConfigFile); |
732 | try |
746 | try |
733 | sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', ''); |
747 | sOverrideGUID := iniConfig.ReadString('Compatibility', 'OverrideGUID', ''); |
734 | if sOverrideGUID <> '' then |
748 | if sOverrideGUID <> '' then |
735 | begin |
749 | begin |
736 | Plugin.FPluginGUIDSet := true; |
750 | Plugin.FPluginGUIDSet := true; |
737 | Plugin.FPluginGUID := StringToGUID(sOverrideGUID); |
751 | Plugin.FPluginGUID := StringToGUID(sOverrideGUID); |
738 | result := true; |
752 | result := true; |
739 | end; |
753 | end; |
740 | finally |
754 | finally |
741 | iniConfig.Free; |
755 | iniConfig.Free; |
742 | end; |
756 | end; |
743 | end; |
757 | end; |
744 | end; |
758 | end; |
745 | 759 | ||
746 | function _AutoOSNotSupportedMode: integer; |
760 | function _AutoOSNotSupportedMode: integer; |
747 | var |
761 | var |
748 | iniConfig: TIniFile; |
762 | iniConfig: TIniFile; |
749 | sPluginConfigFile: string; |
763 | sPluginConfigFile: string; |
750 | begin |
764 | begin |
751 | result := 0; |
765 | result := 0; |
752 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
766 | sPluginConfigFile := ChangeFileExt(dllFile, '.ini'); |
753 | if FileExists(sPluginConfigFile) then |
767 | if FileExists(sPluginConfigFile) then |
754 | begin |
768 | begin |
755 | iniConfig := TIniFile.Create(sPluginConfigFile); |
769 | iniConfig := TIniFile.Create(sPluginConfigFile); |
756 | try |
770 | try |
757 | result := iniConfig.ReadInteger('Compatibility', 'AutoOSNotSupported', 0); |
771 | result := iniConfig.ReadInteger('Compatibility', 'AutoOSNotSupported', 0); |
758 | finally |
772 | finally |
759 | iniConfig.Free; |
773 | iniConfig.Free; |
760 | end; |
774 | end; |
761 | end; |
775 | end; |
762 | end; |
776 | end; |
763 | 777 | ||
764 | procedure _OverwriteStatusToOSNotSupported; |
778 | procedure _OverwriteStatusToOSNotSupported; |
765 | begin |
779 | begin |
766 | Plugin := TUD2Plugin.Create; |
780 | Plugin := TUD2Plugin.Create; |
767 | Plugin.FPluginDLL := dllFile; |
781 | Plugin.FPluginDLL := dllFile; |
768 | statusCode := UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED; |
782 | statusCode := UD2_STATUS_NOTAVAIL_OS_NOT_SUPPORTED; |
769 | Plugin.FIdentificationProcedureStatusCode := statusCode; |
783 | Plugin.FIdentificationProcedureStatusCode := statusCode; |
770 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
784 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
771 | Plugin.FOSNotSupportedEnforced := true; |
785 | Plugin.FOSNotSupportedEnforced := true; |
772 | result := true; |
786 | result := true; |
773 | end; |
787 | end; |
774 | 788 | ||
775 | resourcestring |
789 | resourcestring |
776 | LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded: %s'; |
790 | LNG_DLL_NOT_LOADED = 'Plugin DLL "%s" could not be loaded: %s'; |
777 | LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.'; |
791 | LNG_METHOD_NOT_FOUND = 'Method "%s" not found in plugin "%s". The DLL is probably not a valid plugin DLL.'; |
778 | LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this application.'; |
792 | LNG_INVALID_PLUGIN = 'The plugin "%s" is not a valid plugin for this application.'; |
779 | LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".'; |
793 | LNG_METHOD_FAILURE = 'Error "%s" at method "%s" of plugin "%s".'; |
780 | LNG_EXCEPTION = 'Fatal error while loading "%s" (%s: %s)'; |
794 | LNG_EXCEPTION = 'Fatal error while loading "%s" (%s: %s)'; |
781 | begin |
795 | begin |
782 | result := false; |
796 | result := false; |
783 | startTime := GetTickCount; |
797 | startTime := GetTickCount; |
784 | 798 | ||
785 | try |
799 | try |
786 | bakErrorMode := 0; |
800 | bakErrorMode := 0; |
787 | UD2_SetThreadErrorMode(SEM_FAILCRITICALERRORS, Pointer(bakErrorMode)); |
801 | UD2_SetThreadErrorMode(SEM_FAILCRITICALERRORS, Pointer(bakErrorMode)); |
788 | try |
802 | try |
789 | dllHandle := LoadLibrary(PChar(dllFile)); |
803 | dllHandle := LoadLibrary(PChar(dllFile)); |
790 | if dllHandle = 0 then |
804 | if dllHandle = 0 then |
791 | begin |
805 | begin |
792 | err := GetLastError; |
806 | err := GetLastError; |
793 | 807 | ||
794 | if ((_AutoOSNotSupportedMode = 1) and ((err = ERROR_DLL_NOT_FOUND) or (err = ERROR_PROC_NOT_FOUND))) or |
808 | if ((_AutoOSNotSupportedMode = 1) and ((err = ERROR_DLL_NOT_FOUND) or (err = ERROR_PROC_NOT_FOUND))) or |
795 | (_AutoOSNotSupportedMode >= 2) then |
809 | (_AutoOSNotSupportedMode >= 2) then |
796 | begin |
810 | begin |
797 | _OverwriteStatusToOSNotSupported; |
811 | _OverwriteStatusToOSNotSupported; |
798 | Exit; |
812 | Exit; |
799 | end; |
813 | end; |
800 | 814 | ||
801 | Errors.Add(Format(LNG_DLL_NOT_LOADED, [dllFile, SysErrorMessage(err)])); |
815 | Errors.Add(Format(LNG_DLL_NOT_LOADED, [dllFile, SysErrorMessage(err)])); |
802 | Exit; |
816 | Exit; |
803 | end; |
817 | end; |
804 | try |
818 | try |
805 | @fPluginInterfaceID := GetProcAddress(dllHandle, mnPluginInterfaceID); |
819 | @fPluginInterfaceID := GetProcAddress(dllHandle, mnPluginInterfaceID); |
806 | if not Assigned(fPluginInterfaceID) then |
820 | if not Assigned(fPluginInterfaceID) then |
807 | begin |
821 | begin |
808 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginInterfaceID, dllFile])); |
822 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginInterfaceID, dllFile])); |
809 | Exit; |
823 | Exit; |
810 | end; |
824 | end; |
811 | pluginInterfaceID := fPluginInterfaceID(); |
825 | pluginInterfaceID := fPluginInterfaceID(); |
812 | if not IsEqualGUID(pluginInterfaceID, GUID_USERDETECT2_IDPLUGIN_V1) then |
826 | if not IsEqualGUID(pluginInterfaceID, GUID_USERDETECT2_IDPLUGIN_V1) then |
813 | begin |
827 | begin |
814 | Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile])); |
828 | Errors.Add(Format(LNG_INVALID_PLUGIN, [dllFile])); |
815 | Exit; |
829 | Exit; |
816 | end; |
830 | end; |
817 | 831 | ||
818 | Plugin := TUD2Plugin.Create; |
832 | Plugin := TUD2Plugin.Create; |
819 | Plugin.FPluginDLL := dllFile; |
833 | Plugin.FPluginDLL := dllFile; |
820 | 834 | ||
821 | @fDynamicIdentificationStringW := GetProcAddress(dllHandle, mnDynamicIdentificationStringW); |
835 | @fDynamicIdentificationStringW := GetProcAddress(dllHandle, mnDynamicIdentificationStringW); |
822 | Plugin.FAcceptsDynamicRequests := Assigned(fDynamicIdentificationStringW); |
836 | Plugin.FAcceptsDynamicRequests := Assigned(fDynamicIdentificationStringW); |
823 | 837 | ||
824 | fIdentificationStringW := nil; |
838 | fIdentificationStringW := nil; |
825 | if useDynamicData then |
839 | if useDynamicData then |
826 | begin |
840 | begin |
827 | if not Plugin.AcceptsDynamicRequests then |
841 | if not Plugin.AcceptsDynamicRequests then |
828 | begin |
842 | begin |
829 | // We should not output a fatal error here, because it is likely that the error is caused by the user writing a buggy INI file (specifying a parameter for a non-dynamic plugin) |
843 | // We should not output a fatal error here, because it is likely that the error is caused by the user writing a buggy INI file (specifying a parameter for a non-dynamic plugin) |
830 | (* |
844 | (* |
831 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile])); |
845 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile])); |
832 | Exit; |
846 | Exit; |
833 | *) |
847 | *) |
834 | 848 | ||
835 | // But we just try to find out if the plugin seems to be "OK" |
849 | // But we just try to find out if the plugin seems to be "OK" |
836 | if not Assigned(fIdentificationStringW) then |
850 | if not Assigned(fIdentificationStringW) then |
837 | begin |
851 | begin |
838 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile])); |
852 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDynamicIdentificationStringW, dllFile])); |
839 | Exit; |
853 | Exit; |
840 | end; |
854 | end; |
841 | 855 | ||
842 | Plugin.FIdentificationProcedureStatusCode := UD2_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS; |
856 | Plugin.FIdentificationProcedureStatusCode := UD2_STATUS_NOTAVAIL_DOES_NOT_ACCEPT_DYNAMIC_REQUESTS; |
843 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
857 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
844 | 858 | ||
845 | Exit; |
859 | Exit; |
846 | end; |
860 | end; |
847 | end |
861 | end |
848 | else |
862 | else |
849 | begin |
863 | begin |
850 | @fIdentificationStringW := GetProcAddress(dllHandle, mnIdentificationStringW); |
864 | @fIdentificationStringW := GetProcAddress(dllHandle, mnIdentificationStringW); |
851 | if not Assigned(fIdentificationStringW) then |
865 | if not Assigned(fIdentificationStringW) then |
852 | begin |
866 | begin |
853 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationStringW, dllFile])); |
867 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationStringW, dllFile])); |
854 | Exit; |
868 | Exit; |
855 | end; |
869 | end; |
856 | end; |
870 | end; |
857 | 871 | ||
858 | @fPluginNameW := GetProcAddress(dllHandle, mnPluginNameW); |
872 | @fPluginNameW := GetProcAddress(dllHandle, mnPluginNameW); |
859 | if not Assigned(fPluginNameW) then |
873 | if not Assigned(fPluginNameW) then |
860 | begin |
874 | begin |
861 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginNameW, dllFile])); |
875 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginNameW, dllFile])); |
862 | Exit; |
876 | Exit; |
863 | end; |
877 | end; |
864 | 878 | ||
865 | @fPluginVendorW := GetProcAddress(dllHandle, mnPluginVendorW); |
879 | @fPluginVendorW := GetProcAddress(dllHandle, mnPluginVendorW); |
866 | if not Assigned(fPluginVendorW) then |
880 | if not Assigned(fPluginVendorW) then |
867 | begin |
881 | begin |
868 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginVendorW, dllFile])); |
882 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginVendorW, dllFile])); |
869 | Exit; |
883 | Exit; |
870 | end; |
884 | end; |
871 | 885 | ||
872 | @fPluginVersionW := GetProcAddress(dllHandle, mnPluginVersionW); |
886 | @fPluginVersionW := GetProcAddress(dllHandle, mnPluginVersionW); |
873 | if not Assigned(fPluginVersionW) then |
887 | if not Assigned(fPluginVersionW) then |
874 | begin |
888 | begin |
875 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginVersionW, dllFile])); |
889 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginVersionW, dllFile])); |
876 | Exit; |
890 | Exit; |
877 | end; |
891 | end; |
878 | 892 | ||
879 | @fCheckLicense := GetProcAddress(dllHandle, mnCheckLicense); |
893 | @fCheckLicense := GetProcAddress(dllHandle, mnCheckLicense); |
880 | if not Assigned(fCheckLicense) then |
894 | if not Assigned(fCheckLicense) then |
881 | begin |
895 | begin |
882 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnCheckLicense, dllFile])); |
896 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnCheckLicense, dllFile])); |
883 | Exit; |
897 | Exit; |
884 | end; |
898 | end; |
885 | 899 | ||
886 | @fIdentificationMethodNameW := GetProcAddress(dllHandle, mnIdentificationMethodNameW); |
900 | @fIdentificationMethodNameW := GetProcAddress(dllHandle, mnIdentificationMethodNameW); |
887 | if not Assigned(fIdentificationMethodNameW) then |
901 | if not Assigned(fIdentificationMethodNameW) then |
888 | begin |
902 | begin |
889 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationMethodNameW, dllFile])); |
903 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnIdentificationMethodNameW, dllFile])); |
890 | Exit; |
904 | Exit; |
891 | end; |
905 | end; |
892 | 906 | ||
893 | @fDescribeOwnStatusCodeW := GetProcAddress(dllHandle, mnDescribeOwnStatusCodeW); |
907 | @fDescribeOwnStatusCodeW := GetProcAddress(dllHandle, mnDescribeOwnStatusCodeW); |
894 | if not Assigned(fDescribeOwnStatusCodeW) then |
908 | if not Assigned(fDescribeOwnStatusCodeW) then |
895 | begin |
909 | begin |
896 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDescribeOwnStatusCodeW, dllFile])); |
910 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnDescribeOwnStatusCodeW, dllFile])); |
897 | Exit; |
911 | Exit; |
898 | end; |
912 | end; |
899 | 913 | ||
900 | if not _ApplyCompatibilityGUID then |
914 | if not _ApplyCompatibilityGUID then |
901 | begin |
915 | begin |
902 | @fPluginIdentifier := GetProcAddress(dllHandle, mnPluginIdentifier); |
916 | @fPluginIdentifier := GetProcAddress(dllHandle, mnPluginIdentifier); |
903 | if not Assigned(fPluginIdentifier) then |
917 | if not Assigned(fPluginIdentifier) then |
904 | begin |
918 | begin |
905 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile])); |
919 | Errors.Add(Format(LNG_METHOD_NOT_FOUND, [mnPluginIdentifier, dllFile])); |
906 | Exit; |
920 | Exit; |
907 | end; |
921 | end; |
908 | Plugin.FPluginGUIDSet := true; |
922 | Plugin.FPluginGUIDSet := true; |
909 | Plugin.FPluginGUID := fPluginIdentifier(); |
923 | Plugin.FPluginGUID := fPluginIdentifier(); |
910 | end; |
924 | end; |
911 | 925 | ||
912 | statusCode := fCheckLicense(nil); |
926 | statusCode := fCheckLicense(nil); |
913 | if statusCode.wCategory = UD2_STATUSCAT_FAILED then |
927 | if statusCode.wCategory = UD2_STATUSCAT_FAILED then |
914 | begin |
928 | begin |
915 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnCheckLicense, dllFile])); |
929 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnCheckLicense, dllFile])); |
916 | Exit; |
930 | Exit; |
917 | end; |
931 | end; |
918 | 932 | ||
919 | ZeroMemory(@buf, cchBufferSize); |
933 | ZeroMemory(@buf, cchBufferSize); |
920 | statusCode := fPluginNameW(@buf, cchBufferSize, lngID); |
934 | statusCode := fPluginNameW(@buf, cchBufferSize, lngID); |
921 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginName := PWideChar(@buf) |
935 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginName := PWideChar(@buf) |
922 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginName := '' |
936 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginName := '' |
923 | else |
937 | else |
924 | begin |
938 | begin |
925 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile])); |
939 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginNameW, dllFile])); |
926 | Exit; |
940 | Exit; |
927 | end; |
941 | end; |
928 | 942 | ||
929 | ZeroMemory(@buf, cchBufferSize); |
943 | ZeroMemory(@buf, cchBufferSize); |
930 | statusCode := fPluginVendorW(@buf, cchBufferSize, lngID); |
944 | statusCode := fPluginVendorW(@buf, cchBufferSize, lngID); |
931 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginVendor := PWideChar(@buf) |
945 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginVendor := PWideChar(@buf) |
932 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVendor := '' |
946 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVendor := '' |
933 | else |
947 | else |
934 | begin |
948 | begin |
935 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile])); |
949 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVendorW, dllFile])); |
936 | Exit; |
950 | Exit; |
937 | end; |
951 | end; |
938 | 952 | ||
939 | ZeroMemory(@buf, cchBufferSize); |
953 | ZeroMemory(@buf, cchBufferSize); |
940 | statusCode := fPluginVersionW(@buf, cchBufferSize, lngID); |
954 | statusCode := fPluginVersionW(@buf, cchBufferSize, lngID); |
941 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginVersion := PWideChar(@buf) |
955 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FPluginVersion := PWideChar(@buf) |
942 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVersion := '' |
956 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FPluginVersion := '' |
943 | else |
957 | else |
944 | begin |
958 | begin |
945 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile])); |
959 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnPluginVersionW, dllFile])); |
946 | Exit; |
960 | Exit; |
947 | end; |
961 | end; |
948 | 962 | ||
949 | ZeroMemory(@buf, cchBufferSize); |
963 | ZeroMemory(@buf, cchBufferSize); |
950 | statusCode := fIdentificationMethodNameW(@buf, cchBufferSize); |
964 | statusCode := fIdentificationMethodNameW(@buf, cchBufferSize); |
951 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FIdentificationMethodName := PWideChar(@buf) |
965 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then Plugin.FIdentificationMethodName := PWideChar(@buf) |
952 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FIdentificationMethodName := '' |
966 | else if statusCode.wCategory = UD2_STATUSCAT_NOT_AVAIL then Plugin.FIdentificationMethodName := '' |
953 | else |
967 | else |
954 | begin |
968 | begin |
955 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile])); |
969 | Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationMethodNameW, dllFile])); |
956 | Exit; |
970 | Exit; |
957 | end; |
971 | end; |
958 | 972 | ||
959 | ZeroMemory(@buf, cchBufferSize); |
973 | ZeroMemory(@buf, cchBufferSize); |
960 | 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) |
974 | 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) |
961 | if useDynamicData then |
975 | if useDynamicData then |
962 | begin |
976 | begin |
963 | statusCode := fDynamicIdentificationStringW(@buf, cchBufferSize, PWideChar(dynamicData)); |
977 | statusCode := fDynamicIdentificationStringW(@buf, cchBufferSize, PWideChar(dynamicData)); |
964 | end |
978 | end |
965 | else |
979 | else |
966 | begin |
980 | begin |
967 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
981 | statusCode := fIdentificationStringW(@buf, cchBufferSize); |
968 | end; |
982 | end; |
969 | Plugin.FIdentificationProcedureStatusCode := statusCode; |
983 | Plugin.FIdentificationProcedureStatusCode := statusCode; |
970 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
984 | Plugin.FIdentificationProcedureStatusCodeDescribed := _ErrorLookup(statusCode); |
971 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
985 | if statusCode.wCategory = UD2_STATUSCAT_SUCCESS then |
972 | begin |
986 | begin |
973 | sIdentifier := PWideChar(@buf); |
987 | sIdentifier := PWideChar(@buf); |
974 | if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then |
988 | if UD2_STATUS_Equal(statusCode, UD2_STATUS_OK_MULTILINE, false) then |
975 | begin |
989 | begin |
976 | // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER) |
990 | // Multiple identifiers (e.g. multiple MAC addresses are delimited via UD2_MULTIPLE_ITEMS_DELIMITER) |
977 | SetLength(ResultIdentifiers, 0); |
991 | SetLength(ResultIdentifiers, 0); |
978 | ResultIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier); |
992 | ResultIdentifiers := SplitString(UD2_MULTIPLE_ITEMS_DELIMITER, sIdentifier); |
979 | for i := Low(ResultIdentifiers) to High(ResultIdentifiers) do |
993 | for i := Low(ResultIdentifiers) to High(ResultIdentifiers) do |
980 | begin |
994 | begin |
981 | Plugin.AddIdentification(ResultIdentifiers[i]); |
995 | Plugin.AddIdentification(ResultIdentifiers[i]); |
982 | end; |
996 | end; |
983 | end |
997 | end |
984 | else |
998 | else |
985 | begin |
999 | begin |
986 | Plugin.AddIdentification(sIdentifier); |
1000 | Plugin.AddIdentification(sIdentifier); |
987 | 1001 | ||
988 | SetLength(ResultIdentifiers, 1); |
1002 | SetLength(ResultIdentifiers, 1); |
989 | ResultIdentifiers[0] := sIdentifier; |
1003 | ResultIdentifiers[0] := sIdentifier; |
990 | end; |
1004 | end; |
991 | end |
1005 | end |
992 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
1006 | else if statusCode.wCategory <> UD2_STATUSCAT_NOT_AVAIL then |
993 | begin |
1007 | begin |
994 | if _AutoOSNotSupportedMode >= 3 then |
1008 | if _AutoOSNotSupportedMode >= 3 then |
995 | begin |
1009 | begin |
996 | _OverwriteStatusToOSNotSupported; |
1010 | _OverwriteStatusToOSNotSupported; |
997 | Exit; |
1011 | Exit; |
998 | end; |
1012 | end; |
999 | 1013 | ||
1000 | // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile])); |
1014 | // Errors.Add(Format(LNG_METHOD_FAILURE, [_ErrorLookup(statusCode), mnIdentificationStringW, dllFile])); |
1001 | Errors.Add(Format(LNG_METHOD_FAILURE, [Plugin.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile])); |
1015 | Errors.Add(Format(LNG_METHOD_FAILURE, [Plugin.IdentificationProcedureStatusCodeDescribed, mnIdentificationStringW, dllFile])); |
1002 | Exit; |
1016 | Exit; |
1003 | end; |
1017 | end; |
1004 | 1018 | ||
1005 | result := true; |
1019 | result := true; |
1006 | finally |
1020 | finally |
1007 | if not result and Assigned(Plugin) then FreeAndNil(Plugin); |
1021 | if not result and Assigned(Plugin) then FreeAndNil(Plugin); |
1008 | FreeLibrary(dllHandle); |
1022 | FreeLibrary(dllHandle); |
1009 | end; |
1023 | end; |
1010 | finally |
1024 | finally |
1011 | UD2_SetThreadErrorMode(bakErrorMode, nil); |
1025 | UD2_SetThreadErrorMode(bakErrorMode, nil); |
1012 | 1026 | ||
1013 | if result then |
1027 | if result then |
1014 | begin |
1028 | begin |
1015 | endtime := GetTickCount; |
1029 | endtime := GetTickCount; |
1016 | time := endtime - starttime; |
1030 | time := endtime - starttime; |
1017 | if endtime < starttime then time := High(Cardinal) - time; |
1031 | if endtime < starttime then time := High(Cardinal) - time; |
1018 | Plugin.FLoadingTime := time; |
1032 | Plugin.FLoadingTime := time; |
1019 | end; |
1033 | end; |
1020 | end; |
1034 | end; |
1021 | except |
1035 | except |
1022 | // TODO: when an exception happens in a cdecl DLL, then this code is somehow not |
1036 | // TODO: when an exception happens in a cdecl DLL, then this code is somehow not |
1023 | // executed. Probably the memory is corrupted. Anyway, a cdecl DLL shall NEVER |
1037 | // executed. Probably the memory is corrupted. Anyway, a cdecl DLL shall NEVER |
1024 | // raise an Exception. |
1038 | // raise an Exception. |
1025 | on E: Exception do |
1039 | on E: Exception do |
1026 | begin |
1040 | begin |
1027 | Errors.Add(Format(LNG_EXCEPTION, [dllFile, E.ClassName, E.Message])); |
1041 | Errors.Add(Format(LNG_EXCEPTION, [dllFile, E.ClassName, E.Message])); |
1028 | Exit; |
1042 | Exit; |
1029 | end; |
1043 | end; |
1030 | end; |
1044 | end; |
1031 | end; |
1045 | end; |
1032 | 1046 | ||
1033 | end. |
1047 | end. |
1034 | 1048 |